From 600269f14023584b200a921b35f58d3654e7e10a Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Wed, 7 Dec 2022 16:54:04 +0100 Subject: [PATCH] add tests --- .../rpc-methods/src/restricted/dialog.test.ts | 231 +++--------------- packages/rpc-methods/src/restricted/dialog.ts | 11 +- 2 files changed, 37 insertions(+), 205 deletions(-) diff --git a/packages/rpc-methods/src/restricted/dialog.test.ts b/packages/rpc-methods/src/restricted/dialog.test.ts index d12d218777..034928b906 100644 --- a/packages/rpc-methods/src/restricted/dialog.test.ts +++ b/packages/rpc-methods/src/restricted/dialog.test.ts @@ -1,4 +1,5 @@ import { PermissionType } from '@metamask/permission-controller'; +import { heading, panel, text } from '@metamask/snaps-ui'; import { dialogBuilder, @@ -49,20 +50,17 @@ describe('implementation', () => { method: 'snap_dialog', params: { type: DialogType.Alert, - fields: { - title: 'Foo', - description: 'Bar', - textAreaContent: 'Baz', - }, + ui: panel([heading('foo'), text('bar')]), }, }); expect(hooks.showDialog).toHaveBeenCalledTimes(1); - expect(hooks.showDialog).toHaveBeenCalledWith('foo', DialogType.Alert, { - title: 'Foo', - description: 'Bar', - textAreaContent: 'Baz', - }); + expect(hooks.showDialog).toHaveBeenCalledWith( + 'foo', + DialogType.Alert, + panel([heading('foo'), text('bar')]), + undefined, + ); }); }); @@ -75,11 +73,7 @@ describe('implementation', () => { method: 'snap_dialog', params: { type: DialogType.Confirmation, - fields: { - title: 'Foo', - description: 'Bar', - textAreaContent: 'Baz', - }, + ui: panel([heading('foo'), text('bar')]), }, }); @@ -87,11 +81,8 @@ describe('implementation', () => { expect(hooks.showDialog).toHaveBeenCalledWith( 'foo', DialogType.Confirmation, - { - title: 'Foo', - description: 'Bar', - textAreaContent: 'Baz', - }, + panel([heading('foo'), text('bar')]), + undefined, ); }); }); @@ -105,20 +96,18 @@ describe('implementation', () => { method: 'snap_dialog', params: { type: DialogType.Prompt, - fields: { - title: 'Foo', - description: 'Bar', - placeholder: 'Baz', - }, + ui: panel([heading('foo'), text('bar')]), + placeholder: 'foobar', }, }); expect(hooks.showDialog).toHaveBeenCalledTimes(1); - expect(hooks.showDialog).toHaveBeenCalledWith('foo', DialogType.Prompt, { - title: 'Foo', - description: 'Bar', - placeholder: 'Baz', - }); + expect(hooks.showDialog).toHaveBeenCalledWith( + 'foo', + DialogType.Prompt, + panel([heading('foo'), text('bar')]), + 'foobar', + ); }); }); @@ -169,12 +158,12 @@ describe('implementation', () => { it.each([ { type: DialogType.Alert }, - { type: DialogType.Alert, fields: null }, - { type: DialogType.Alert, fields: false }, - { type: DialogType.Alert, fields: '' }, - { type: DialogType.Alert, fields: 'abc' }, - { type: DialogType.Alert, fields: 2 }, - { type: DialogType.Alert, fields: [] }, + { type: DialogType.Alert, ui: null }, + { type: DialogType.Alert, ui: false }, + { type: DialogType.Alert, ui: '' }, + { type: DialogType.Alert, ui: 'abc' }, + { type: DialogType.Alert, ui: 2 }, + { type: DialogType.Alert, ui: [] }, ])('rejects invalid fields', async (value) => { const hooks = getMockDialogHooks(); const implementation = getDialogImplementation(hooks); @@ -190,128 +179,9 @@ describe('implementation', () => { ); }); - it.each([undefined, null, false, 2, [], {}, new (class {})()])( - 'rejects invalid titles', - async (value) => { - const hooks = getMockDialogHooks(); - const implementation = getDialogImplementation(hooks); - - await expect( - implementation({ - context: { origin: 'foo' }, - method: 'snap_dialog', - params: { - type: DialogType.Alert, - fields: { - title: value, - description: 'Bar', - textAreaContent: 'Baz', - } as any, - }, - }), - ).rejects.toThrow( - /Invalid params: At path: fields.title -- Expected a string, but received: .*\./u, - ); - }, - ); - - it('rejects titles with invalid length', async () => { - const hooks = getMockDialogHooks(); - const implementation = getDialogImplementation(hooks); - - await expect( - implementation({ - context: { origin: 'foo' }, - method: 'snap_dialog', - params: { - type: DialogType.Alert, - fields: { - title: '', - description: 'Bar', - textAreaContent: 'Baz', - }, - }, - }), - ).rejects.toThrow( - 'Invalid params: At path: fields.title -- Expected a string with a length between `1` and `40` but received one with a length of `0`.', - ); - }); - - it.each([true, 2, [], {}, new (class {})()])( - 'rejects invalid descriptions', - async (value) => { - const hooks = getMockDialogHooks(); - const implementation = getDialogImplementation(hooks); - - await expect( - implementation({ - context: { origin: 'foo' }, - method: 'snap_dialog', - params: { - type: DialogType.Alert, - fields: { - title: 'Foo', - description: value, - textAreaContent: 'Baz', - } as any, - }, - }), - ).rejects.toThrow( - /Invalid params: At path: fields.description -- Expected a string, but received: .*\./u, - ); - }, - ); - - it('rejects too long descriptions', async () => { - const hooks = getMockDialogHooks(); - const implementation = getDialogImplementation(hooks); - - await expect( - implementation({ - context: { origin: 'foo' }, - method: 'snap_dialog', - params: { - type: DialogType.Alert, - fields: { - title: 'Foo', - description: 'a'.repeat(141), - textAreaContent: 'Baz', - } as any, - }, - }), - ).rejects.toThrow( - 'Invalid params: At path: fields.description -- Expected a string with a length between `1` and `140` but received one with a length of `141`.', - ); - }); - - it.each([true, 2, [], {}, new (class {})()])( - 'rejects invalid text area contents', - async (value) => { - const hooks = getMockDialogHooks(); - const implementation = getDialogImplementation(hooks); - - await expect( - implementation({ - context: { origin: 'foo' }, - method: 'snap_dialog', - params: { - type: DialogType.Alert, - fields: { - title: 'Foo', - description: 'Bar', - textAreaContent: value, - } as any, - }, - }), - ).rejects.toThrow( - /Invalid params: At path: fields\.textAreaContent -- Expected a string, but received: .*\./u, - ); - }, - ); - it.each([true, 2, [], {}, new (class {})()])( 'rejects invalid placeholder contents', - async (value) => { + async (value: any) => { const hooks = getMockDialogHooks(); const implementation = getDialogImplementation(hooks); @@ -321,59 +191,32 @@ describe('implementation', () => { method: 'snap_dialog', params: { type: DialogType.Prompt, - fields: { - title: 'Foo', - description: 'Bar', - placeholder: value, - } as any, + ui: panel([heading('foo'), text('bar')]), + placeholder: value, }, }), ).rejects.toThrow( - /Invalid params: At path: fields\.placeholder -- Expected a string, but received: .*\./u, + /Invalid params: At path: placeholder -- Expected a string, but received: .*\./u, ); }, ); - it('rejects too long text area contents', async () => { + it('rejects placeholders with invalid length', async () => { const hooks = getMockDialogHooks(); const implementation = getDialogImplementation(hooks); - await expect( - implementation({ - context: { origin: 'foo' }, - method: 'snap_dialog', - params: { - type: DialogType.Alert, - fields: { - title: 'Foo', - description: 'Bar', - textAreaContent: 'a'.repeat(1801), - } as any, - }, - }), - ).rejects.toThrow( - 'Invalid params: At path: fields.textAreaContent -- Expected a string with a length between `1` and `1800` but received one with a length of `1801`.', - ); - }); - - it('rejects textAreaContent field for prompts', async () => { - const hooks = getMockDialogHooks(); - const implementation = getDialogImplementation(hooks); await expect( implementation({ context: { origin: 'foo' }, method: 'snap_dialog', params: { type: DialogType.Prompt, - fields: { - title: 'Foo', - description: 'Bar', - textAreaContent: 'Baz', - } as any, + ui: panel([heading('foo'), text('bar')]), + placeholder: '', }, }), ).rejects.toThrow( - 'Invalid params: Prompts may not specify a "textAreaContent" field.', + 'Invalid params: At path: placeholder -- Expected a string with a length between `1` and `40` but received one with a length of `0`.', ); }); @@ -388,12 +231,8 @@ describe('implementation', () => { method: 'snap_dialog', params: { type, - fields: { - title: 'Foo', - description: 'Bar', - textAreaContent: 'Baz', - placeholder: 'Foobar', - } as any, + ui: panel([heading('foo'), text('bar')]), + placeholder: 'foobar', }, }), ).rejects.toThrow( diff --git a/packages/rpc-methods/src/restricted/dialog.ts b/packages/rpc-methods/src/restricted/dialog.ts index 8dc407b167..e229d07842 100644 --- a/packages/rpc-methods/src/restricted/dialog.ts +++ b/packages/rpc-methods/src/restricted/dialog.ts @@ -38,7 +38,7 @@ type ShowDialog = ( snapId: string, type: DialogType, ui: Component, - placeholder: Placeholder, + placeholder?: Placeholder, ) => Promise; export type DialogMethodHooks = { @@ -124,9 +124,9 @@ const PromptParametersStruct = object({ }); const DialogParametersStruct = union([ - PromptParametersStruct, AlertParametersStruct, ConfirmationParametersStruct, + PromptParametersStruct, ]); export type DialogParameters = Infer; @@ -206,13 +206,6 @@ function getValidatedParams( if (error instanceof StructError) { const { key, type: errorType } = error; - if (key === 'textAreaContent' && errorType === 'never') { - throw ethErrors.rpc.invalidParams({ - message: - 'Invalid params: Prompts may not specify a "textAreaContent" field.', - }); - } - if (key === 'placeholder' && errorType === 'never') { throw ethErrors.rpc.invalidParams({ message: