From 8801827856e2149be752a89fbdc0bff524b16fb8 Mon Sep 17 00:00:00 2001 From: Vladislav Kibenko Date: Tue, 2 Jul 2024 22:18:58 +0300 Subject: [PATCH 1/2] fix(sdk): fix invalid qr scanner behavior --- .../components/QRScanner/QRScanner.test.ts | 74 +++++++++++++++++++ .../sdk/src/components/QRScanner/QRScanner.ts | 21 +++--- 2 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 packages/sdk/src/components/QRScanner/QRScanner.test.ts diff --git a/packages/sdk/src/components/QRScanner/QRScanner.test.ts b/packages/sdk/src/components/QRScanner/QRScanner.test.ts new file mode 100644 index 000000000..6797e8166 --- /dev/null +++ b/packages/sdk/src/components/QRScanner/QRScanner.test.ts @@ -0,0 +1,74 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + +import { createWindow } from '@test-utils/createWindow.js'; +import { dispatchWindowMessageEvent } from '@test-utils/dispatchWindowMessageEvent.js'; +import { resetMiniAppsEventEmitter } from '@/bridge/events/event-emitter/singleton.js'; + +import { QRScanner } from './QRScanner.js'; + +beforeEach(() => { + createWindow(); +}); + +afterEach(() => { + vi.restoreAllMocks(); + resetMiniAppsEventEmitter(); +}); + +describe('open', () => { + it('should call the web_app_open_scan_qr_popup method with the specified text', async () => { + const postEvent = vi.fn(); + const qr = new QRScanner(false, '10', postEvent); + qr.open('Scan a QR'); + + expect(postEvent).toBeCalledTimes(1); + expect(postEvent).toBeCalledWith('web_app_open_scan_qr_popup', { + text: 'Scan a QR', + }); + }); + + it('should resolve with null if the scan_qr_popup_closed event was received', async () => { + const qr = new QRScanner(false, '10', vi.fn() as any); + const promise = qr.open('Scan a QR'); + + dispatchWindowMessageEvent('scan_qr_popup_closed', {}); + + await expect(promise).resolves.toBeNull(); + }); + + it('should resolve with qr context specified in the qr_text_received event', async () => { + const qr = new QRScanner(false, '10', vi.fn() as any); + const promise = qr.open('Scan a QR'); + + dispatchWindowMessageEvent('qr_text_received', { + data: 'qr content', + }); + + await expect(promise).resolves.toBe('qr content'); + }); + + it('should throw an error, if the scanner was opened several times without closing', async () => { + const qr = new QRScanner(false, '10', vi.fn() as any); + qr.open('Scan a QR'); + await expect(qr.open('again')).rejects.toThrow('The scanner is already opened'); + }); + + it('should set isOpened = true after call and false after qr_text_received or scan_qr_popup_closed events were called', async () => { + const qr = new QRScanner(false, '10', vi.fn() as any); + + expect(qr.isOpened).toBe(false); + let promise = qr.open(); + expect(qr.isOpened).toBe(true); + dispatchWindowMessageEvent('qr_text_received', { + data: 'qr content', + }); + await promise; + expect(qr.isOpened).toBe(false); + + promise = qr.open(); + expect(qr.isOpened).toBe(true); + dispatchWindowMessageEvent('scan_qr_popup_closed', {}); + await promise; + expect(qr.isOpened).toBe(false); + }); +}); \ No newline at end of file diff --git a/packages/sdk/src/components/QRScanner/QRScanner.ts b/packages/sdk/src/components/QRScanner/QRScanner.ts index 684c75f45..26a9b86e5 100644 --- a/packages/sdk/src/components/QRScanner/QRScanner.ts +++ b/packages/sdk/src/components/QRScanner/QRScanner.ts @@ -19,7 +19,7 @@ export class QRScanner extends WithSupportsAndTrackableState; /** - * Opens scanner with specified title shown to user. Method returns promise - * with scanned QR content in case, it was scanned. It will contain null in - * case, scanner was closed. + * Opens the scanner with the specified title shown to user. + * The method returns a promise with a scanned QR content and null if the scanner was closed. * @param text - title to display. */ async open(text?: string): Promise; async open(textOrOptions?: QRScannerOpenOptions | string): Promise { if (this.isOpened) { - throw new Error('QR scanner is already opened.'); + throw new Error('The scanner is already opened'); } const { text, capture }: QRScannerOpenOptions = ( @@ -79,9 +77,10 @@ export class QRScanner extends WithSupportsAndTrackableState Date: Tue, 2 Jul 2024 22:20:10 +0300 Subject: [PATCH 2/2] docs(changeset): Fix invalid QR scanner behavior related to the invalid isOpened property updates. --- .changeset/tasty-turtles-dress.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/tasty-turtles-dress.md diff --git a/.changeset/tasty-turtles-dress.md b/.changeset/tasty-turtles-dress.md new file mode 100644 index 000000000..ab5fdcc7d --- /dev/null +++ b/.changeset/tasty-turtles-dress.md @@ -0,0 +1,5 @@ +--- +"@tma.js/sdk": patch +--- + +Fix invalid QR scanner behavior related to the invalid isOpened property updates.