diff --git a/src/types/relying-party-options.spec.ts b/src/types/relying-party-options.spec.ts index ffddd656..8a82b141 100644 --- a/src/types/relying-party-options.spec.ts +++ b/src/types/relying-party-options.spec.ts @@ -19,6 +19,54 @@ describe('RelyingPartyOptions', () => { expect(result.success).toBe(true); }); + it('should fail validation with a negative pollingIntervalInMilliseconds', () => { + const invalidData = { + url: 'https://example.com', + connectionOptions: { + pollingIntervalInMilliseconds: -500 + } + }; + + const result = RelyingPartyOptionsSchema.safeParse(invalidData); + expect(result.success).toBe(false); + }); + + it('should fail validation with zero pollingIntervalInMilliseconds', () => { + const invalidData = { + url: 'https://example.com', + connectionOptions: { + pollingIntervalInMilliseconds: 0 + } + }; + + const result = RelyingPartyOptionsSchema.safeParse(invalidData); + expect(result.success).toBe(false); + }); + + it('should fail validation with a zero timeoutInMilliseconds', () => { + const invalidData = { + url: 'https://example.com', + connectionOptions: { + timeoutInMilliseconds: 0 + } + }; + + const result = RelyingPartyOptionsSchema.safeParse(invalidData); + expect(result.success).toBe(false); + }); + + it('should fail validation with a negative timeoutInMilliseconds', () => { + const invalidData = { + url: 'https://example.com', + connectionOptions: { + timeoutInMilliseconds: -120000 + } + }; + + const result = RelyingPartyOptionsSchema.safeParse(invalidData); + expect(result.success).toBe(false); + }); + it('should validate with correct relying party options and string window options', () => { const validData = { url: 'https://example.com', @@ -52,6 +100,48 @@ describe('RelyingPartyOptions', () => { expect(result.success).toBe(false); }); + it('should fail validation with zero width for the signer window', () => { + const invalidData = { + url: 'https://example.com', + windowOptions: { + position: 'center', + width: 0, + height: 300 + } + }; + + const result = RelyingPartyOptionsSchema.safeParse(invalidData); + expect(result.success).toBe(false); + }); + + it('should fail validation with zero height for the signer window', () => { + const invalidData = { + url: 'https://example.com', + windowOptions: { + position: 'center', + width: 400, + height: 0 + } + }; + + const result = RelyingPartyOptionsSchema.safeParse(invalidData); + expect(result.success).toBe(false); + }); + + it('should pass validation with positive width and height for the signer window', () => { + const validData = { + url: 'https://example.com', + windowOptions: { + position: 'center', + width: 400, + height: 300 + } + }; + + const result = RelyingPartyOptionsSchema.safeParse(validData); + expect(result.success).toBe(true); + }); + it('should fail validation with incorrect connectionOptions object', () => { const invalidData = { url: 'https://example.com', diff --git a/src/types/relying-party-options.ts b/src/types/relying-party-options.ts index 3f167d99..a930dc61 100644 --- a/src/types/relying-party-options.ts +++ b/src/types/relying-party-options.ts @@ -3,18 +3,20 @@ import {z} from 'zod'; const ConnectionOptionsSchema = z.object({ /** * Specifies the interval in milliseconds at which the signer is checked (polled) to determine if it is ready. + * Must be a positive number. * * @default 500 - The default polling interval is set to 500 milliseconds. */ - pollingIntervalInMilliseconds: z.number().optional(), + pollingIntervalInMilliseconds: z.number().positive().optional(), /** * Specifies the maximum duration in milliseconds for attempting to establish a connection to the signer. * If the connection is not established within this duration, the process will time out. + * Must be a positive number. * * @default 120_000 - The default timeout is set to 120,000 milliseconds (2 minutes). */ - timeoutInMilliseconds: z.number().optional() + timeoutInMilliseconds: z.number().positive().optional() }); export type ConnectionOptions = z.infer; @@ -26,14 +28,14 @@ const WindowOptionsSchema = z.object({ position: z.enum(['top-right', 'center']), /** - * Specifies the width of the signer window. + * Specifies a width greater than zero of the signer window. */ - width: z.number(), + width: z.number().positive(), /** - * Specifies the height of the signer window. + * Specifies a height greater than zero of the signer window. */ - height: z.number(), + height: z.number().positive(), /** * Optional features for the signer Window object. diff --git a/src/types/relying-party-request.specs.ts b/src/types/relying-party-request.spec.ts similarity index 62% rename from src/types/relying-party-request.specs.ts rename to src/types/relying-party-request.spec.ts index 6634ca51..75a10e18 100644 --- a/src/types/relying-party-request.specs.ts +++ b/src/types/relying-party-request.spec.ts @@ -26,5 +26,23 @@ describe('RelyingPartyRequests', () => { const result = RelyingPartyRequestOptionsSchema.safeParse(invalidData); expect(result.success).toBe(false); }); + + it('should fail validation with a non-positive timeoutInMilliseconds', () => { + const invalidData = { + timeoutInMilliseconds: -500 + }; + + const result = RelyingPartyRequestOptionsSchema.safeParse(invalidData); + expect(result.success).toBe(false); + }); + + it('should fail validation with a zero timeoutInMilliseconds', () => { + const invalidData = { + timeoutInMilliseconds: 0 + }; + + const result = RelyingPartyRequestOptionsSchema.safeParse(invalidData); + expect(result.success).toBe(false); + }); }); }); diff --git a/src/types/relying-party-requests.ts b/src/types/relying-party-requests.ts index 70b3a785..712cb878 100644 --- a/src/types/relying-party-requests.ts +++ b/src/types/relying-party-requests.ts @@ -5,8 +5,9 @@ export const RelyingPartyRequestOptionsTimeoutSchema = z.object({ /** * Specifies the maximum duration in milliseconds for attempting to request an interaction with the relying party. * If the relying party does not answer within this duration, the process will time out. + * Must be a positive number. */ - timeoutInMilliseconds: z.number() + timeoutInMilliseconds: z.number().positive() }); export const RelyingPartyRequestOptionsSchema = z diff --git a/src/types/signer-sessions.spec.ts b/src/types/signer-sessions.spec.ts index 8bb503a9..b3f3a233 100644 --- a/src/types/signer-sessions.spec.ts +++ b/src/types/signer-sessions.spec.ts @@ -48,6 +48,26 @@ describe('Signer-sessions', () => { expect(() => SessionPermissionsSchema.parse(invalidData)).toThrow(); }); + it('should fail validation with a negative createdAt', () => { + const invalidData = { + scopes, + createdAt: -1000, + updatedAt: Date.now() + }; + + expect(() => SessionPermissionsSchema.parse(invalidData)).toThrow(); + }); + + it('should fail validation with a zero createdAt', () => { + const invalidData = { + scopes, + createdAt: 0, + updatedAt: Date.now() + }; + + expect(() => SessionPermissionsSchema.parse(invalidData)).toThrow(); + }); + it('should fail validation if updatedAt is not a number', () => { const invalidData = { scopes, @@ -67,6 +87,26 @@ describe('Signer-sessions', () => { expect(() => SessionPermissionsSchema.parse(invalidData)).toThrow(); }); + it('should fail validation with a negative updatedAt', () => { + const invalidData = { + scopes, + createdAt: Date.now(), + updatedAt: -1000 + }; + + expect(() => SessionPermissionsSchema.parse(invalidData)).toThrow(); + }); + + it('should fail validation with a zero updatedAt', () => { + const invalidData = { + scopes, + createdAt: Date.now(), + updatedAt: 0 + }; + + expect(() => SessionPermissionsSchema.parse(invalidData)).toThrow(); + }); + it('should fail validation if scopes is missing', () => { const invalidData = { createdAt: Date.now(), diff --git a/src/types/signer-sessions.ts b/src/types/signer-sessions.ts index 52ae790a..c3fe1558 100644 --- a/src/types/signer-sessions.ts +++ b/src/types/signer-sessions.ts @@ -2,8 +2,8 @@ import {z} from 'zod'; import {IcrcScopeSchema} from './icrc-responses'; export const SessionTimestampsSchema = z.object({ - createdAt: z.number(), - updatedAt: z.number() + createdAt: z.number().positive(), + updatedAt: z.number().positive() }); export const SessionIcrcScopeSchema = IcrcScopeSchema.merge(SessionTimestampsSchema);