From 91d1229023e2eb4f9306aa2c1251c128761ff722 Mon Sep 17 00:00:00 2001 From: William Grant Date: Mon, 20 May 2024 17:49:05 +1000 Subject: [PATCH] feat: made good progress on avatar place holder unit test feat added stubCrypto function --- .../AvatarPlaceHolder/AvatarPlaceHolder.tsx | 2 +- ts/test/components/AvatarPlaceHolder_test.tsx | 96 ++++++++++++++++--- ts/test/test-utils/utils/stubbing.ts | 7 ++ 3 files changed, 91 insertions(+), 14 deletions(-) diff --git a/ts/components/avatar/AvatarPlaceHolder/AvatarPlaceHolder.tsx b/ts/components/avatar/AvatarPlaceHolder/AvatarPlaceHolder.tsx index 811567d53..a09e077c4 100644 --- a/ts/components/avatar/AvatarPlaceHolder/AvatarPlaceHolder.tsx +++ b/ts/components/avatar/AvatarPlaceHolder/AvatarPlaceHolder.tsx @@ -55,7 +55,7 @@ function useHashBasedOnPubkey(pubkey: string) { } // eslint-disable-next-line more/no-then - void sha512FromPubkeyOneAtAtime(pubkey).then(sha => { + void AvatarPlaceHolderUtils.sha512FromPubkeyOneAtAtime(pubkey).then(sha => { if (isInProgress) { setIsLoading(false); // Generate the seed simulate the .hashCode as Java diff --git a/ts/test/components/AvatarPlaceHolder_test.tsx b/ts/test/components/AvatarPlaceHolder_test.tsx index 5bdb2601a..18edd4498 100644 --- a/ts/test/components/AvatarPlaceHolder_test.tsx +++ b/ts/test/components/AvatarPlaceHolder_test.tsx @@ -1,21 +1,91 @@ /* eslint-disable import/no-extraneous-dependencies */ -import chai from 'chai'; +import chai, { expect } from 'chai'; import chaiDom from 'chai-dom'; +import { isEqual } from 'lodash'; +import Sinon from 'sinon'; +import { AvatarSize } from '../../components/avatar/Avatar'; +import { + AvatarPlaceHolder, + AvatarPlaceHolderUtils, +} from '../../components/avatar/AvatarPlaceHolder/AvatarPlaceHolder'; +import { MemberAvatarPlaceHolder } from '../../components/icon/MemberAvatarPlaceHolder'; +import { allowOnlyOneAtATime } from '../../session/utils/Promise'; +import { TestUtils } from '../test-utils'; +import { stubCrypto } from '../test-utils/utils'; +import { cleanup, renderComponent, waitFor } from './renderComponent'; chai.use(chaiDom); describe('AvatarPlaceHolder', () => { - it('should render', async () => { - // ARRANGE - // TODO have proper values - // render(); - // ACT - // TODO proper actions - // await userEvent.click(screen.getByText('0xasdfgggjkdks')); - // await screen.findByRole('heading'); - // ASSERT - // TODO proper expectations - // expect(screen.getByRole('heading')).text('hello there'); - // expect(screen.getByRole('button')).to.have.attribute('disabled').match('true'); + const pubkey = TestUtils.generateFakePubKeyStr(); + const displayName = 'Hello World'; + + beforeEach(async () => { + TestUtils.stubWindowLog(); + + // NOTE this is the best way I have found to stub the crypto module for now + const crypto = await stubCrypto(); + // code must match the original exactly + Sinon.stub(AvatarPlaceHolderUtils, 'sha512FromPubkeyOneAtAtime').returns( + allowOnlyOneAtATime(`sha512FromPubkey-${'pubkey'}`, async () => { + const buf = await crypto.subtle.digest('SHA-512', new TextEncoder().encode(pubkey)); + + return Array.prototype.map + .call(new Uint8Array(buf), (x: any) => `00${x.toString(16)}`.slice(-2)) + .join(''); + }) + ); + }); + + afterEach(() => { + Sinon.restore(); + cleanup(); + }); + + it('should render an svg', async () => { + // TODO[epic=ses-968] Fix warnings that appear when we run this test. + const result = renderComponent( + + ); + + // we need to wait for the component to render after calculating the hash + await waitFor(() => { + result.getByText('HW'); + }); + + const el = result.getByTestId('avatar-placeholder'); + expect(el.outerHTML, 'should not be null').to.not.equal(null); + expect(el.outerHTML, 'should not be undefined').to.not.equal(undefined); + expect(el.outerHTML, 'should not be an empty string').to.not.equal(''); + expect(el.tagName, 'should be an svg').to.equal('svg'); }); + + it('should render the MemberAvatarPlaceholder if we are loading or there is no hash', async () => { + const result = renderComponent( + + ); + const el = result.getByTestId('avatar-placeholder'); + + const result2 = renderComponent( + + ); + const el2 = result2.getByTestId('member-avatar-placeholder'); + + // The data test ids are different so we don't use the outerHTML for comparison + expect(isEqual(el.innerHTML, el2.innerHTML)).to.equal(true); + }); + + // TODO it should render the correct theme colors + // TODO given a pubkey it should render the correct color + // TODO given a name it should render the correct initials }); diff --git a/ts/test/test-utils/utils/stubbing.ts b/ts/test/test-utils/utils/stubbing.ts index 8a5f63a7b..5a3a95bf4 100644 --- a/ts/test/test-utils/utils/stubbing.ts +++ b/ts/test/test-utils/utils/stubbing.ts @@ -155,3 +155,10 @@ export const stubStorage = () => { }, }; }; + +/** The crypto module from the browser is not accessible during tests so we use the NodeJS module instead */ +export const stubCrypto = async () => { + const nodeCrypto = await import('node:crypto'); + + return nodeCrypto; +};