Skip to content

Commit

Permalink
feat(schema, api-client): Migrate user types and schemas to @keyshade…
Browse files Browse the repository at this point in the history
…/schema (#535)
  • Loading branch information
muntaxir4 authored Nov 18, 2024
1 parent 9283b22 commit c24695e
Show file tree
Hide file tree
Showing 7 changed files with 275 additions and 36 deletions.
2 changes: 1 addition & 1 deletion packages/api-client/src/controllers/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
ResendEmailChangeOTPRequest,
DeleteSelfResponse,
ResendEmailChangeOTPResponse
} from '@api-client/types/user.types'
} from '@keyshade/schema'

export default class UserController {
private apiClient: APIClient
Expand Down
33 changes: 0 additions & 33 deletions packages/api-client/src/types/user.types.d.ts

This file was deleted.

5 changes: 3 additions & 2 deletions packages/schema/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ export * from './api-key'

export * from './auth/auth'

export * from './enums'

export * from './environment'
export * from './integration'
export * from './project'
export * from './secret'
export * from './user'
export * from './variable'

export * from './workspace/workspace'

export * from './workspace-role'

export * from './enums'
2 changes: 2 additions & 0 deletions packages/schema/src/index.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export type TForkProject = z.infer<typeof ForkProjectSchema>
export type TCreateSecret = z.infer<typeof CreateSecretSchema>
export type TUpdateSecret = z.infer<typeof UpdateSecretSchema>

export * from './user/index.types'

export type TCreateVariable = z.infer<typeof CreateVariableSchema>
export type TUpdateVariable = z.infer<typeof UpdateVariableSchema>

Expand Down
42 changes: 42 additions & 0 deletions packages/schema/src/user/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { z } from 'zod'
import { WorkspaceSchema } from '@/workspace/workspace'

export const GetSelfResponseSchema = z.object({
id: z.string(),
email: z.string().email(),
name: z.string(),
profilePictureUrl: z.string().nullable(),
isActive: z.boolean(),
isOnboardingFinished: z.boolean(),
isAdmin: z.boolean(),
authProvider: z.string(),
defaultWorkspace: WorkspaceSchema
})

export const UpdateSelfRequestSchema = z.object({
name: z.string().optional(),
profilePictureUrl: z.string().optional(),
isOnboardingFinished: z.boolean().optional(),
email: z.string().email().optional()
})

export const UpdateSelfResponseSchema = GetSelfResponseSchema.partial().omit({
defaultWorkspace: true
})

export const DeleteSelfRequestSchema = z.void()

export const DeleteSelfResponseSchema = z.void()

export const ValidateEmailChangeOTPRequestSchema = z.object({
otp: z.string().min(6).max(6)
})

export const ValidateEmailChangeOTPResponseSchema =
GetSelfResponseSchema.partial().omit({
defaultWorkspace: true
})

export const ResendEmailChangeOTPRequestSchema = z.void()

export const ResendEmailChangeOTPResponseSchema = z.void()
38 changes: 38 additions & 0 deletions packages/schema/src/user/index.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { z } from 'zod'
import {
GetSelfResponseSchema,
UpdateSelfRequestSchema,
UpdateSelfResponseSchema,
DeleteSelfRequestSchema,
DeleteSelfResponseSchema,
ValidateEmailChangeOTPRequestSchema,
ValidateEmailChangeOTPResponseSchema,
ResendEmailChangeOTPRequestSchema,
ResendEmailChangeOTPResponseSchema
} from '.'

export type GetSelfResponse = z.infer<typeof GetSelfResponseSchema>

export type UpdateSelfRequest = z.infer<typeof UpdateSelfRequestSchema>

export type UpdateSelfResponse = z.infer<typeof UpdateSelfResponseSchema>

export type DeleteSelfRequest = z.infer<typeof DeleteSelfRequestSchema>

export type DeleteSelfResponse = z.infer<typeof DeleteSelfResponseSchema>

export type ValidateEmailChangeOTPRequest = z.infer<
typeof ValidateEmailChangeOTPRequestSchema
>

export type ValidateEmailChangeOTPResponse = z.infer<
typeof ValidateEmailChangeOTPResponseSchema
>

export type ResendEmailChangeOTPRequest = z.infer<
typeof ResendEmailChangeOTPRequestSchema
>

export type ResendEmailChangeOTPResponse = z.infer<
typeof ResendEmailChangeOTPResponseSchema
>
189 changes: 189 additions & 0 deletions packages/schema/tests/user.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
import {
GetSelfResponseSchema,
UpdateSelfRequestSchema,
UpdateSelfResponseSchema,
DeleteSelfRequestSchema,
DeleteSelfResponseSchema,
ValidateEmailChangeOTPRequestSchema,
ValidateEmailChangeOTPResponseSchema,
ResendEmailChangeOTPRequestSchema,
ResendEmailChangeOTPResponseSchema
} from '@/user'

describe('User Schema Tests', () => {
// Tests for GetSelfResponseSchema
it('should validate a valid GetSelfResponseSchema', () => {
const result = GetSelfResponseSchema.safeParse({
id: 'user123',
email: '[email protected]',
name: 'John Doe',
profilePictureUrl: null,
isActive: true,
isOnboardingFinished: false,
isAdmin: false,
authProvider: 'email',
defaultWorkspace: {
id: 'workspace123',
name: 'My Workspace',
slug: 'my-workspace',
icon: 'icon.png',
isFreeTier: true,
createdAt: '2024-10-01T00:00:00Z',
updatedAt: '2024-10-01T00:00:00Z',
ownerId: 'owner123',
isDefault: true,
lastUpdatedBy: 'user123'
}
})
expect(result.success).toBe(true)
})

it('should fail validation for invalid GetSelfResponseSchema', () => {
const result = GetSelfResponseSchema.safeParse({
email: 'invalid-email',
name: 'John Doe'
// Missing required fields and invalid email
})
expect(result.success).toBe(false)
expect(result.error?.issues.length).toBe(8)
})

// Tests for UpdateSelfRequestSchema
it('should validate a valid UpdateSelfRequestSchema', () => {
const result = UpdateSelfRequestSchema.safeParse({
name: 'Jane Doe',
email: '[email protected]',
isOnboardingFinished: true
})
expect(result.success).toBe(true)
})

it('should fail validation for invalid UpdateSelfRequestSchema', () => {
const result = UpdateSelfRequestSchema.safeParse({
email: 'invalid-email-format'
})
expect(result.success).toBe(false)
expect(result.error?.issues.length).toBe(1)
})

// Tests for UpdateSelfResponseSchema
it('should validate a valid UpdateSelfResponseSchema', () => {
const result = UpdateSelfResponseSchema.safeParse({
id: 'user123',
email: '[email protected]',
name: 'Jane Doe',
isActive: true
})
expect(result.success).toBe(true)
})

it('should fail validation for invalid UpdateSelfResponseSchema', () => {
const result = UpdateSelfResponseSchema.safeParse({
id: 123, // Should be a string
email: '[email protected]'
})
expect(result.success).toBe(false)
expect(result.error?.issues.length).toBe(1)
})

// Tests for DeleteSelfRequestSchema
it('should validate a valid DeleteSelfRequestSchema', () => {
const result = DeleteSelfRequestSchema.safeParse(undefined)
expect(result.success).toBe(true)
})

it('should fail validation for invalid DeleteSelfRequestSchema', () => {
const result = DeleteSelfRequestSchema.safeParse({
unexpectedField: 'value'
})
expect(result.success).toBe(false)
expect(result.error?.issues.length).toBe(1)
})

// Tests for DeleteSelfResponseSchema
it('should validate a valid DeleteSelfResponseSchema', () => {
const result = DeleteSelfResponseSchema.safeParse(undefined)
expect(result.success).toBe(true)
})

it('should fail validation for invalid DeleteSelfResponseSchema', () => {
const result = DeleteSelfResponseSchema.safeParse({
success: true
})
expect(result.success).toBe(false)
expect(result.error?.issues.length).toBe(1)
})

// Tests for ValidateEmailChangeOTPRequestSchema
it('should validate a valid ValidateEmailChangeOTPRequestSchema', () => {
const result = ValidateEmailChangeOTPRequestSchema.safeParse({
otp: '123456'
})
expect(result.success).toBe(true)
})

it('should fail validation for OTP of length other than 6 ValidateEmailChangeOTPRequestSchema', () => {
const result = ValidateEmailChangeOTPRequestSchema.safeParse({
otp: '234' // Should be a 6 digit string
})
expect(result.success).toBe(false)
expect(result.error?.issues.length).toBe(1)
})

it('should fail validation for invalid ValidateEmailChangeOTPRequestSchema', () => {
const result = ValidateEmailChangeOTPRequestSchema.safeParse({
otp: 123456 // Should be a string
})
expect(result.success).toBe(false)
expect(result.error?.issues.length).toBe(1)
})

// Tests for ValidateEmailChangeOTPResponseSchema
it('should validate a valid ValidateEmailChangeOTPResponseSchema', () => {
const result = ValidateEmailChangeOTPResponseSchema.safeParse({
id: 'user123',
email: '[email protected]',
name: 'John Doe',
profilePictureUrl: null,
isActive: true,
isOnboardingFinished: false,
isAdmin: false,
authProvider: 'email'
})
expect(result.success).toBe(true)
})

it('should fail validation for invalid ValidateEmailChangeOTPResponseSchema', () => {
const result = ValidateEmailChangeOTPResponseSchema.safeParse(undefined)
expect(result.success).toBe(false)
expect(result.error?.issues.length).toBe(1)
})

// Tests for ResendEmailChangeOTPRequestSchema
it('should validate a valid ResendEmailChangeOTPRequestSchema', () => {
const result = ResendEmailChangeOTPRequestSchema.safeParse(undefined)
expect(result.success).toBe(true)
})

it('should fail validation for invalid ResendEmailChangeOTPRequestSchema', () => {
const result = ResendEmailChangeOTPRequestSchema.safeParse({
extraField: 'value' // Should not have any fields
})
expect(result.success).toBe(false)
expect(result.error?.issues.length).toBe(1)
})

// Tests for ResendEmailChangeOTPResponseSchema
it('should validate a valid ResendEmailChangeOTPResponseSchema', () => {
const result = ResendEmailChangeOTPResponseSchema.safeParse(undefined)
expect(result.success).toBe(true)
})

it('should fail validation for invalid ResendEmailChangeOTPResponseSchema', () => {
const result = ResendEmailChangeOTPResponseSchema.safeParse({
success: true
})
expect(result.success).toBe(false)
expect(result.error?.issues.length).toBe(1)
})
})

0 comments on commit c24695e

Please sign in to comment.