From 974d8110d05bda4e362c4d35b72034bf534e257d Mon Sep 17 00:00:00 2001 From: muntaxir4 Date: Sat, 16 Nov 2024 17:09:00 +0530 Subject: [PATCH] feat(schema): Add environment schemas and types along with tests. Also modify project schemas to reflect new environment --- packages/schema/src/environment.ts | 8 - .../schema/src/environment/environment.ts | 56 +++ .../src/environment/environment.types.ts | 54 +++ packages/schema/src/index.ts | 3 +- packages/schema/src/index.types.ts | 5 +- packages/schema/src/project/project.ts | 4 +- packages/schema/tests/environment.spec.ts | 320 +++++++++++++++++- packages/schema/tests/project.spec.ts | 2 +- 8 files changed, 429 insertions(+), 23 deletions(-) delete mode 100644 packages/schema/src/environment.ts create mode 100644 packages/schema/src/environment/environment.ts create mode 100644 packages/schema/src/environment/environment.types.ts diff --git a/packages/schema/src/environment.ts b/packages/schema/src/environment.ts deleted file mode 100644 index 834acb4e..00000000 --- a/packages/schema/src/environment.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { z } from 'zod' - -export const CreateEnvironmentSchema = z.object({ - name: z.string(), - description: z.string().optional() -}) - -export const UpdateEnvironmentSchema = CreateEnvironmentSchema.partial() diff --git a/packages/schema/src/environment/environment.ts b/packages/schema/src/environment/environment.ts new file mode 100644 index 00000000..1ca54ad2 --- /dev/null +++ b/packages/schema/src/environment/environment.ts @@ -0,0 +1,56 @@ +import { z } from 'zod' +import { PageRequestSchema, PageResponseSchema } from '@/pagination/pagination' + +export const EnvironmentSchema = z.object({ + id: z.string(), + name: z.string(), + slug: z.string(), + description: z.string().nullable(), + createdAt: z.string(), + updatedAt: z.string(), + lastUpdatedById: z.string(), + projectId: z.string() +}) + +export const CreateEnvironmentRequestSchema = z.object({ + name: z.string(), + description: z.string().optional(), + projectId: z.string() +}) + +export const CreateEnvironmentResponseSchema = EnvironmentSchema + +export const UpdateEnvironmentRequestSchema = + CreateEnvironmentRequestSchema.omit({ projectId: true }) + .partial() + .extend({ slug: z.string() }) + +export const UpdateEnvironmentResponseSchema = EnvironmentSchema + +export const GetEnvironmentRequestSchema = z.object({ + slug: z.string() +}) + +export const GetEnvironmentResponseSchema = EnvironmentSchema + +export const GetAllEnvironmentsOfProjectRequestSchema = + PageRequestSchema.extend({ + projectSlug: z.string() + }) + +export const GetAllEnvironmentsOfProjectResponseSchema = PageResponseSchema( + EnvironmentSchema.extend({ + lastUpdatedBy: z.object({ + id: z.string(), + name: z.string(), + email: z.string(), + profilePictureUrl: z.string().nullable() + }) + }) +) + +export const DeleteEnvironmentRequestSchema = z.object({ + slug: z.string() +}) + +export const DeleteEnvironmentResponseSchema = z.void() diff --git a/packages/schema/src/environment/environment.types.ts b/packages/schema/src/environment/environment.types.ts new file mode 100644 index 00000000..f7d97b4e --- /dev/null +++ b/packages/schema/src/environment/environment.types.ts @@ -0,0 +1,54 @@ +import { z } from 'zod' +import { + EnvironmentSchema, + CreateEnvironmentRequestSchema, + CreateEnvironmentResponseSchema, + UpdateEnvironmentRequestSchema, + UpdateEnvironmentResponseSchema, + GetEnvironmentRequestSchema, + GetEnvironmentResponseSchema, + GetAllEnvironmentsOfProjectRequestSchema, + GetAllEnvironmentsOfProjectResponseSchema, + DeleteEnvironmentRequestSchema, + DeleteEnvironmentResponseSchema +} from './environment' + +export type Environment = z.infer + +export type CreateEnvironmentRequest = z.infer< + typeof CreateEnvironmentRequestSchema +> + +export type CreateEnvironmentResponse = z.infer< + typeof CreateEnvironmentResponseSchema +> + +export type UpdateEnvironmentRequest = z.infer< + typeof UpdateEnvironmentRequestSchema +> + +export type UpdateEnvironmentResponse = z.infer< + typeof UpdateEnvironmentResponseSchema +> + +export type GetEnvironmentRequest = z.infer + +export type GetEnvironmentResponse = z.infer< + typeof GetEnvironmentResponseSchema +> + +export type GetAllEnvironmentsOfProjectRequest = z.infer< + typeof GetAllEnvironmentsOfProjectRequestSchema +> + +export type GetAllEnvironmentsOfProjectResponse = z.infer< + typeof GetAllEnvironmentsOfProjectResponseSchema +> + +export type DeleteEnvironmentRequest = z.infer< + typeof DeleteEnvironmentRequestSchema +> + +export type DeleteEnvironmentResponse = z.infer< + typeof DeleteEnvironmentResponseSchema +> diff --git a/packages/schema/src/index.ts b/packages/schema/src/index.ts index 96f1a2bf..197b6324 100644 --- a/packages/schema/src/index.ts +++ b/packages/schema/src/index.ts @@ -6,7 +6,8 @@ export * from './api-key' export * from './auth/auth' -export * from './environment' +export * from './environment/environment' + export * from './integration' export * from './project/project' diff --git a/packages/schema/src/index.types.ts b/packages/schema/src/index.types.ts index 4d77fef5..40838ab0 100644 --- a/packages/schema/src/index.types.ts +++ b/packages/schema/src/index.types.ts @@ -1,6 +1,5 @@ import { z } from 'zod' import { CreateApiKeySchema, UpdateApiKeySchema } from './api-key' -import { CreateEnvironmentSchema, UpdateEnvironmentSchema } from './environment' import { CreateIntegrationSchema, UpdateIntegrationSchema } from './integration' import { CreateSecretSchema, UpdateSecretSchema } from './secret' import { CreateVariableSchema, UpdateVariableSchema } from './variable' @@ -18,8 +17,8 @@ export type TUpdateApiKey = z.infer // Export types from auth.types.ts export * from './auth/auth.types' -export type TCreateEnvironment = z.infer -export type TUpdateEnvironment = z.infer +// Export types from environment.types.ts +export * from './environment/environment.types' export type TCreateIntegration = z.infer export type TUpdateIntegration = z.infer diff --git a/packages/schema/src/project/project.ts b/packages/schema/src/project/project.ts index 5b960cb2..ad9ff539 100644 --- a/packages/schema/src/project/project.ts +++ b/packages/schema/src/project/project.ts @@ -1,6 +1,6 @@ import { z } from 'zod' import { PageRequestSchema, PageResponseSchema } from '@/pagination/pagination' -import { CreateEnvironmentSchema } from '@/environment' +import { CreateEnvironmentRequestSchema } from '@/environment/environment' import { projectAccessLevelEnum } from '@/enums' export const ProjectSchema = z @@ -31,7 +31,7 @@ export const CreateProjectRequestSchema = z.object({ workspaceSlug: z.string(), description: z.string().optional(), storePrivateKey: z.boolean().optional(), - environments: CreateEnvironmentSchema.array().optional(), + environments: CreateEnvironmentRequestSchema.array().optional(), accessLevel: projectAccessLevelEnum }) diff --git a/packages/schema/tests/environment.spec.ts b/packages/schema/tests/environment.spec.ts index 0adbb494..cba00b6e 100644 --- a/packages/schema/tests/environment.spec.ts +++ b/packages/schema/tests/environment.spec.ts @@ -1,27 +1,331 @@ -import { CreateEnvironmentSchema } from '@/environment' +import { + EnvironmentSchema, + CreateEnvironmentRequestSchema, + CreateEnvironmentResponseSchema, + UpdateEnvironmentRequestSchema, + UpdateEnvironmentResponseSchema, + GetEnvironmentRequestSchema, + GetEnvironmentResponseSchema, + GetAllEnvironmentsOfProjectRequestSchema, + GetAllEnvironmentsOfProjectResponseSchema, + DeleteEnvironmentRequestSchema, + DeleteEnvironmentResponseSchema +} from '@/environment/environment' describe('Environment Schema Tests', () => { - it('should validate if proper input is specified', () => { - const result = CreateEnvironmentSchema.safeParse({ + // Tests for EnvironmentSchema + it('should validate a valid EnvironmentSchema', () => { + const result = EnvironmentSchema.safeParse({ + id: 'env123', + name: 'Development', + slug: 'development', + description: null, + createdAt: '2024-10-01T00:00:00Z', + updatedAt: '2024-10-01T00:00:00Z', + lastUpdatedById: 'user123', + projectId: 'project123' + }) + expect(result.success).toBe(true) + }) + + it('should not validate an invalid EnvironmentSchema with missing fields', () => { + const result = EnvironmentSchema.safeParse({ + id: 'env123', + name: 'Development' + // Missing required fields + }) + expect(result.success).toBe(false) + expect(result.error?.issues).toHaveLength(6) + }) + + it('should not validate an invalid EnvironmentSchema with incorrect types', () => { + const result = EnvironmentSchema.safeParse({ + id: 'env123', + name: 'Development', + slug: 'development', + description: 'Development environment', + createdAt: '2024-10-01T00:00:00Z', + updatedAt: '2024-10-01T00:00:00Z', + lastUpdatedById: 'user123', + projectId: 123 // Should be a string + }) + expect(result.success).toBe(false) + expect(result.error?.issues).toHaveLength(1) + }) + + // Tests for CreateEnvironmentRequestSchema + it('should validate if proper input is specified for CreateEnvironmentRequestSchema', () => { + const result = CreateEnvironmentRequestSchema.safeParse({ + name: 'test', + description: 'test description', + projectId: 'project123' + }) + expect(result.success).toBe(true) + }) + + it('should not validate if invalid values are specified for CreateEnvironmentRequestSchema', () => { + const result = CreateEnvironmentRequestSchema.safeParse({ + name: 123, + projectId: 'project123' + }) + expect(result.success).toBe(false) + expect(result.error?.issues).toHaveLength(1) + }) + + it('should not validate if required values are not specified for CreateEnvironmentRequestSchema', () => { + const result = CreateEnvironmentRequestSchema.safeParse({ name: 'test' }) + expect(result.success).toBe(false) + expect(result.error?.issues).toHaveLength(1) + }) + + // Tests for CreateEnvironmentResponseSchema + it('should validate a valid CreateEnvironmentResponseSchema', () => { + const result = CreateEnvironmentResponseSchema.safeParse({ + id: 'env123', + name: 'Development', + slug: 'development', + description: 'Development environment', + createdAt: '2024-10-01T00:00:00Z', + updatedAt: '2024-10-01T00:00:00Z', + lastUpdatedById: 'user123', + projectId: 'project123' + }) + expect(result.success).toBe(true) + }) + + it('should not validate an invalid CreateEnvironmentResponseSchema with multiple incorrect types', () => { + const result = CreateEnvironmentResponseSchema.safeParse({ + id: 123, // Should be a string + name: 'Development', + slug: 'development', + description: 456, // Should be a string or null + createdAt: '2024-10-01T00:00:00Z', + updatedAt: '2024-10-01T00:00:00Z', + lastUpdatedById: 'user123', + projectId: true // Should be a string + }) + expect(result.success).toBe(false) + expect(result.error?.issues).toHaveLength(3) + }) + + // Tests for UpdateEnvironmentRequestSchema + it('should validate if proper input is specified for UpdateEnvironmentRequestSchema', () => { + const result = UpdateEnvironmentRequestSchema.safeParse({ + name: 'updatedTest', + slug: 'updated-slug' + }) + expect(result.success).toBe(true) + }) + + it('should not validate if invalid values are specified for UpdateEnvironmentRequestSchema', () => { + const result = UpdateEnvironmentRequestSchema.safeParse({ + name: 123, + slug: 'updated-slug' + }) + expect(result.success).toBe(false) + expect(result.error?.issues).toHaveLength(1) + }) + + // Tests for UpdateEnvironmentResponseSchema + it('should validate a valid UpdateEnvironmentResponseSchema', () => { + const result = UpdateEnvironmentResponseSchema.safeParse({ + id: 'env123', + name: 'Development', + slug: 'development', + description: 'Development environment', + createdAt: '2024-10-01T00:00:00Z', + updatedAt: '2024-10-01T00:00:00Z', + lastUpdatedById: 'user123', + projectId: 'project123' + }) + expect(result.success).toBe(true) + }) + it('should not validate an invalid UpdateEnvironmentResponseSchema with multiple incorrect types', () => { + const result = UpdateEnvironmentResponseSchema.safeParse({ + id: 123, // Should be a string + name: 'Development', + slug: 'development', + description: 456, // Should be a string or null + createdAt: '2024-10-01T00:00:00Z', + updatedAt: '2024-10-01T00:00:00Z', + lastUpdatedById: 'user123', + projectId: true // Should be a string + }) + expect(result.success).toBe(false) + expect(result.error?.issues).toHaveLength(3) + }) + + // Tests for GetEnvironmentRequestSchema + it('should validate if proper input is specified for GetEnvironmentRequestSchema', () => { + const result = GetEnvironmentRequestSchema.safeParse({ + slug: 'test-slug' + }) expect(result.success).toBe(true) }) - it('should not validate if invalid values are specified', () => { - const result = CreateEnvironmentSchema.safeParse({ - name: 123 + it('should not validate if invalid values are specified for GetEnvironmentRequestSchema', () => { + const result = GetEnvironmentRequestSchema.safeParse({ + slug: 123 + }) + expect(result.success).toBe(false) + expect(result.error?.issues).toHaveLength(1) + }) + + // Tests for GetEnvironmentResponseSchema + it('should validate a valid GetEnvironmentResponseSchema', () => { + const result = GetEnvironmentResponseSchema.safeParse({ + id: 'env123', + name: 'Development', + slug: 'development', + description: 'Development environment', + createdAt: '2024-10-01T00:00:00Z', + updatedAt: '2024-10-01T00:00:00Z', + lastUpdatedById: 'user123', + projectId: 'project123' }) + expect(result.success).toBe(true) + }) + it('should not validate an invalid GetEnvironmentResponseSchema with multiple incorrect types', () => { + const result = GetEnvironmentResponseSchema.safeParse({ + id: 123, // Should be a string + name: 'Development', + slug: 'development', + description: 456, // Should be a string or null + createdAt: '2024-10-01T00:00:00Z', + updatedAt: '2024-10-01T00:00:00Z', + lastUpdatedById: 'user123', + projectId: true // Should be a string + }) + expect(result.success).toBe(false) + expect(result.error?.issues).toHaveLength(3) + }) + + // Tests for GetAllEnvironmentsOfProjectRequestSchema + it('should validate if proper input is specified for GetAllEnvironmentsOfProjectRequestSchema', () => { + const result = GetAllEnvironmentsOfProjectRequestSchema.safeParse({ + projectSlug: 'project-slug', + page: 1, + limit: 10 + }) + expect(result.success).toBe(true) + }) + + it('should not validate if invalid values are specified for GetAllEnvironmentsOfProjectRequestSchema', () => { + const result = GetAllEnvironmentsOfProjectRequestSchema.safeParse({ + projectSlug: 123, + page: 'one', + limit: 'ten' + }) + expect(result.success).toBe(false) + expect(result.error?.issues).toHaveLength(3) + }) + + // Tests for GetAllEnvironmentsOfProjectResponseSchema + it('should validate a valid GetAllEnvironmentsOfProjectResponseSchema', () => { + const result = GetAllEnvironmentsOfProjectResponseSchema.safeParse({ + items: [ + { + id: 'env123', + name: 'Development', + slug: 'development', + description: 'Development environment', + createdAt: '2024-10-01T00:00:00Z', + updatedAt: '2024-10-01T00:00:00Z', + lastUpdatedById: 'user123', + projectId: 'project123', + lastUpdatedBy: { + id: 'user123', + name: 'John Doe', + email: 'john.doe@example.com', + profilePictureUrl: 'http://example.com/profile.jpg' + } + } + ], + metadata: { + page: 1, + perPage: 10, + pageCount: 1, + totalCount: 1, + links: { + self: 'http://example.com/page/1', + first: 'http://example.com/page/1', + previous: null, + next: null, + last: 'http://example.com/page/1' + } + } + }) + expect(result.success).toBe(true) + }) + + it('should not validate an invalid GetAllEnvironmentsOfProjectResponseSchema with incorrect types', () => { + const result = GetAllEnvironmentsOfProjectResponseSchema.safeParse({ + items: [ + { + id: 'env123', + name: 'Development', + slug: 'development', + description: 'Development environment', + createdAt: '2024-10-01T00:00:00Z', + updatedAt: '2024-10-01T00:00:00Z', + lastUpdatedById: 'user123', + projectId: 'project123', + lastUpdatedBy: { + id: 'user123', + name: 'John Doe', + email: 'john.doe@example.com', + profilePictureUrl: null + } + } + ], + metadata: { + page: 'one', // Should be a number + perPage: 10, + pageCount: 1, + totalCount: 1, + links: { + self: 'http://example.com/page/1', + first: 'http://example.com/page/1', + previous: null, + next: null, + last: 'http://example.com/page/1' + } + } + }) expect(result.success).toBe(false) expect(result.error?.issues).toHaveLength(1) }) - it('should not validate if required values are not specified', () => { - const result = CreateEnvironmentSchema.safeParse({}) + // Tests for DeleteEnvironmentRequestSchema + it('should validate if proper input is specified for DeleteEnvironmentRequestSchema', () => { + const result = DeleteEnvironmentRequestSchema.safeParse({ + slug: 'test-slug' + }) + expect(result.success).toBe(true) + }) + it('should not validate if invalid values are specified for DeleteEnvironmentRequestSchema', () => { + const result = DeleteEnvironmentRequestSchema.safeParse({ + slug: 123 + }) expect(result.success).toBe(false) expect(result.error?.issues).toHaveLength(1) }) + + // Tests for DeleteEnvironmentResponseSchema + it('should validate a valid DeleteEnvironmentResponseSchema', () => { + const result = DeleteEnvironmentResponseSchema.safeParse(undefined) + expect(result.success).toBe(true) + }) + + it('should not validate an invalid DeleteEnvironmentResponseSchema', () => { + const result = DeleteEnvironmentResponseSchema.safeParse({ + unexpectedField: 'value' + }) + expect(result.success).toBe(false) + }) }) diff --git a/packages/schema/tests/project.spec.ts b/packages/schema/tests/project.spec.ts index 12166283..956326a2 100644 --- a/packages/schema/tests/project.spec.ts +++ b/packages/schema/tests/project.spec.ts @@ -88,7 +88,7 @@ describe('Project Schema Tests', () => { name: 'Project Test', workspaceSlug: 'workspace123', accessLevel: projectAccessLevelEnum.Enum.PRIVATE, - environments: [{ name: 'Environment 1' }] + environments: [{ name: 'Environment 1', projectId: 'project123' }] }) expect(result.success).toBe(true)