-
Notifications
You must be signed in to change notification settings - Fork 298
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #880 from grafana/jorlando/mobile-app-qr-code
Fetch/Display Mobile App QR Code
- Loading branch information
Showing
28 changed files
with
8,067 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 0 additions & 8 deletions
8
grafana-plugin/src/containers/MobileAppVerification/MobileAppVerification.module.css
This file was deleted.
Oops, something went wrong.
182 changes: 182 additions & 0 deletions
182
grafana-plugin/src/containers/MobileAppVerification/MobileAppVerification.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
import React from 'react'; | ||
|
||
import { render, screen } from '@testing-library/react'; | ||
import userEvent from '@testing-library/user-event'; | ||
|
||
import { UserStore } from 'models/user/user'; | ||
import { User } from 'models/user/user.types'; | ||
import { RootStore } from 'state'; | ||
import { useStore as useStoreOriginal } from 'state/useStore'; | ||
|
||
import MobileAppVerification from './MobileAppVerification'; | ||
|
||
jest.mock('state/useStore'); | ||
|
||
const useStore = useStoreOriginal as jest.Mock<ReturnType<typeof useStoreOriginal>>; | ||
|
||
const mockUseStore = (rest?: any, connected = false) => { | ||
const store = { | ||
userStore: { | ||
currentUser: { | ||
messaging_backends: { | ||
MOBILE_APP: { connected }, | ||
}, | ||
} as unknown as User, | ||
...(rest ? rest : {}), | ||
} as unknown as UserStore, | ||
} as unknown as RootStore; | ||
|
||
useStore.mockReturnValue(store); | ||
|
||
return store; | ||
}; | ||
|
||
const USER_PK = '8585'; | ||
const BACKEND = 'MOBILE_APP'; | ||
|
||
describe('MobileAppVerification', () => { | ||
test('it shows a loading message if it is currently fetching the QR code', async () => { | ||
const { userStore } = mockUseStore({ | ||
sendBackendConfirmationCode: jest.fn().mockResolvedValueOnce('dfd'), | ||
}); | ||
|
||
const component = render(<MobileAppVerification userPk={USER_PK} />); | ||
expect(component.container).toMatchSnapshot(); | ||
|
||
expect(userStore.sendBackendConfirmationCode).toHaveBeenCalledTimes(1); | ||
expect(userStore.sendBackendConfirmationCode).toHaveBeenCalledWith(USER_PK, BACKEND); | ||
}); | ||
|
||
test('it shows a message when the mobile app is already connected', async () => { | ||
const { userStore } = mockUseStore( | ||
{ | ||
sendBackendConfirmationCode: jest.fn().mockResolvedValueOnce('dfd'), | ||
}, | ||
true | ||
); | ||
|
||
const component = render(<MobileAppVerification userPk={USER_PK} />); | ||
expect(component.container).toMatchSnapshot(); | ||
|
||
expect(userStore.sendBackendConfirmationCode).toHaveBeenCalledTimes(0); | ||
}); | ||
|
||
test('it shows an error message if there was an error fetching the QR code', async () => { | ||
const { userStore } = mockUseStore({ | ||
sendBackendConfirmationCode: jest.fn().mockRejectedValueOnce('dfd'), | ||
}); | ||
|
||
const component = render(<MobileAppVerification userPk={USER_PK} />); | ||
await screen.findByText(/.*error fetching your QR code.*/); | ||
|
||
expect(component.container).toMatchSnapshot(); | ||
|
||
expect(userStore.sendBackendConfirmationCode).toHaveBeenCalledTimes(1); | ||
expect(userStore.sendBackendConfirmationCode).toHaveBeenCalledWith(USER_PK, BACKEND); | ||
}); | ||
|
||
test("it shows a QR code if the app isn't already connected", async () => { | ||
const { userStore } = mockUseStore({ | ||
sendBackendConfirmationCode: jest.fn().mockResolvedValueOnce('dfd'), | ||
}); | ||
|
||
const component = render(<MobileAppVerification userPk={USER_PK} />); | ||
await screen.findByText(/.*the QR code is only valid for one minute.*/); | ||
|
||
expect(component.container).toMatchSnapshot(); | ||
|
||
expect(userStore.sendBackendConfirmationCode).toHaveBeenCalledTimes(1); | ||
expect(userStore.sendBackendConfirmationCode).toHaveBeenCalledWith(USER_PK, BACKEND); | ||
}); | ||
|
||
test('if we disconnect the app, it disconnects and fetches a new QR code', async () => { | ||
const { userStore } = mockUseStore( | ||
{ | ||
sendBackendConfirmationCode: jest.fn().mockResolvedValueOnce('dfd'), | ||
unlinkBackend: jest.fn().mockResolvedValueOnce('asdfadsfafds'), | ||
}, | ||
true | ||
); | ||
|
||
const component = render(<MobileAppVerification userPk={USER_PK} />); | ||
|
||
const user = userEvent.setup(); | ||
const button = await screen.findByRole('button'); | ||
|
||
// click the disconnect button, which opens the modal | ||
await user.click(button); | ||
// click the confirm button within the modal, which actually triggers the callback | ||
await user.click(screen.getByText('Remove')); | ||
|
||
await screen.findByText(/.*the QR code is only valid for one minute.*/); | ||
|
||
expect(component.container).toMatchSnapshot(); | ||
|
||
expect(userStore.sendBackendConfirmationCode).toHaveBeenCalledTimes(1); | ||
expect(userStore.sendBackendConfirmationCode).toHaveBeenCalledWith(USER_PK, BACKEND); | ||
|
||
expect(userStore.unlinkBackend).toHaveBeenCalledTimes(1); | ||
expect(userStore.unlinkBackend).toHaveBeenCalledWith(USER_PK, BACKEND); | ||
}); | ||
|
||
test('it shows a loading message if it is currently disconnecting', async () => { | ||
const { userStore } = mockUseStore( | ||
{ | ||
sendBackendConfirmationCode: jest.fn().mockResolvedValueOnce('dfd'), | ||
unlinkBackend: jest.fn().mockResolvedValueOnce('aaa'), | ||
}, | ||
true | ||
); | ||
|
||
const component = render(<MobileAppVerification userPk={USER_PK} />); | ||
|
||
const user = userEvent.setup(); | ||
const button = await screen.findByRole('button'); | ||
|
||
// click the disconnect button, which opens the modal | ||
await user.click(button); | ||
// click the confirm button within the modal, which actually triggers the callback | ||
// this is maybe a bit "hacky" but by not awaiting the below promise it allows us to check the loading state.. | ||
user.click(screen.getByText('Remove')); | ||
|
||
// wait for loading state | ||
await screen.findByText(/.*Loading.*/); | ||
|
||
expect(component.container).toMatchSnapshot(); | ||
|
||
expect(userStore.sendBackendConfirmationCode).toHaveBeenCalledTimes(1); | ||
expect(userStore.sendBackendConfirmationCode).toHaveBeenCalledWith(USER_PK, BACKEND); | ||
|
||
expect(userStore.unlinkBackend).toHaveBeenCalledTimes(1); | ||
expect(userStore.unlinkBackend).toHaveBeenCalledWith(USER_PK, BACKEND); | ||
}); | ||
|
||
test('it shows an error message if there was an error disconnecting the mobile app', async () => { | ||
const { userStore } = mockUseStore( | ||
{ | ||
sendBackendConfirmationCode: jest.fn().mockResolvedValueOnce('dfd'), | ||
unlinkBackend: jest.fn().mockRejectedValueOnce('asdfadsfafds'), | ||
}, | ||
true | ||
); | ||
|
||
const component = render(<MobileAppVerification userPk={USER_PK} />); | ||
|
||
const user = userEvent.setup(); | ||
const button = await screen.findByRole('button'); | ||
|
||
// click the disconnect button, which opens the modal | ||
await user.click(button); | ||
// click the confirm button within the modal, which actually triggers the callback | ||
await user.click(screen.getByText('Remove')); | ||
|
||
await screen.findByText(/.*error disconnecting your mobile app.*/); | ||
|
||
expect(component.container).toMatchSnapshot(); | ||
|
||
expect(userStore.sendBackendConfirmationCode).toHaveBeenCalledTimes(0); | ||
|
||
expect(userStore.unlinkBackend).toHaveBeenCalledTimes(1); | ||
expect(userStore.unlinkBackend).toHaveBeenCalledWith(USER_PK, BACKEND); | ||
}); | ||
}); |
Oops, something went wrong.