Skip to content

Commit

Permalink
fix: breaks the avatar if you hit the button adding an invalid link (#…
Browse files Browse the repository at this point in the history
…31467)

Co-authored-by: dougfabris <[email protected]>
Co-authored-by: Guilherme Gazzo <[email protected]>
  • Loading branch information
3 people authored Jan 26, 2024
1 parent e7d3cde commit 61a655f
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 21 deletions.
5 changes: 5 additions & 0 deletions .changeset/tough-candles-argue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fix an issue that breaks the avatar if you hit the button adding an invalid link
19 changes: 14 additions & 5 deletions apps/meteor/client/components/avatar/BaseAvatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,23 @@ import React, { useState } from 'react';

export type BaseAvatarProps = Omit<AvatarProps, 'is'>;

const BaseAvatar: FC<BaseAvatarProps> = ({ size, ...props }) => {
const [error, setError] = useState<unknown>(false);
const BaseAvatar: FC<BaseAvatarProps> = ({ onError, ...props }) => {
const [isLoading, setIsLoading] = useState<unknown>(false);

if (error) {
return <Skeleton aria-hidden variant='rect' {...props} />;
if (isLoading) {
return <Skeleton aria-hidden variant='rect' onError={onError} {...props} />;
}

return <Avatar aria-hidden onError={setError} size={size} {...props} />;
return (
<Avatar
aria-hidden
onError={(event) => {
setIsLoading(true);
onError?.(event);
}}
{...props}
/>
);
};

export default BaseAvatar;
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { IUser, AvatarObject } from '@rocket.chat/core-typings';
import { Box, Button, TextInput, Avatar, IconButton } from '@rocket.chat/fuselage';
import { Box, Button, TextInput, Avatar, IconButton, Label } from '@rocket.chat/fuselage';
import { useUniqueId } from '@rocket.chat/fuselage-hooks';
import { useToastMessageDispatch, useSetting, useTranslation } from '@rocket.chat/ui-contexts';
import type { ReactElement, ChangeEvent } from 'react';
import React, { useState, useCallback } from 'react';
Expand All @@ -24,6 +25,7 @@ function UserAvatarEditor({ currentUsername, username, setAvatarObj, disabled, e
const rotateImages = useSetting('FileUpload_RotateImages');
const [avatarFromUrl, setAvatarFromUrl] = useState('');
const [newAvatarSource, setNewAvatarSource] = useState<string>();
const imageUrlField = useUniqueId();
const dispatchToastMessage = useToastMessageDispatch();

const setUploadedPreview = useCallback(
Expand All @@ -44,7 +46,7 @@ function UserAvatarEditor({ currentUsername, username, setAvatarObj, disabled, e

const [clickUpload] = useSingleFileInput(setUploadedPreview);

const clickUrl = (): void => {
const handleAddUrl = (): void => {
setNewAvatarSource(avatarFromUrl);
setAvatarObj({ avatarUrl: avatarFromUrl });
};
Expand Down Expand Up @@ -75,8 +77,11 @@ function UserAvatarEditor({ currentUsername, username, setAvatarObj, disabled, e
<UserAvatar
size='x124'
url={url}
key={url}
data-qa-id='UserAvatarEditor'
username={currentUsername || ''}
etag={etag}
onError={() => dispatchToastMessage({ type: 'error', message: t('error-invalid-image-url') })}
style={{
objectFit: 'contain',
imageOrientation: rotateImages ? 'from-image' : 'none',
Expand All @@ -94,14 +99,17 @@ function UserAvatarEditor({ currentUsername, username, setAvatarObj, disabled, e
disabled={disabled || !avatarFromUrl}
title={t('Add_URL')}
mi={4}
onClick={clickUrl}
onClick={handleAddUrl}
data-qa-id='UserAvatarEditorSetAvatarLink'
/>
<UserAvatarSuggestions disabled={disabled} onSelectOne={handleSelectSuggestion} />
</Box>
<Box mis={4}>{t('Use_url_for_avatar')}</Box>
<Label htmlFor={imageUrlField} mis={4}>
{t('Use_url_for_avatar')}
</Label>
<TextInput
data-qa-id='UserAvatarEditorLink'
id={imageUrlField}
flexGrow={0}
placeholder={t('Use_url_for_avatar')}
value={avatarFromUrl}
Expand Down
1 change: 1 addition & 0 deletions apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -2036,6 +2036,7 @@
"error-invalid-file-width": "Invalid file width",
"error-invalid-from-address": "You informed an invalid FROM address.",
"error-invalid-inquiry": "Invalid inquiry",
"error-invalid-image-url": "Invalid image URL",
"error-invalid-integration": "Invalid integration",
"error-invalid-message": "Invalid message",
"error-invalid-method": "Invalid method",
Expand Down
28 changes: 16 additions & 12 deletions apps/meteor/tests/e2e/account-profile.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,27 +41,31 @@ test.describe.serial('settings-account-profile', () => {

await expect(poHomeChannel.tabs.userInfoUsername).toHaveText(newUsername);
})
test('change avatar', async ({ page }) => {
await test.step('expect change avatar image by upload', async () => {

test.describe('Avatar', () => {
test('should change avatar image by uploading file', async () => {
await poAccountProfile.inputImageFile.setInputFiles('./tests/e2e/fixtures/files/test-image.jpeg');

await poAccountProfile.btnSubmit.click();
await expect(page.locator('.rcx-toastbar.rcx-toastbar--success').first()).toBeVisible();

await expect(poAccountProfile.userAvatarEditor).toHaveAttribute('src');
});

test('should change avatar image from url', async () => {
await poAccountProfile.inputAvatarLink.fill('https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50');
await poAccountProfile.btnSetAvatarLink.click();

await test.step('expect to close toastbar', async () => {
await page.locator('.rcx-toastbar.rcx-toastbar--success').first().click();
await poAccountProfile.btnSubmit.click();
await expect(poAccountProfile.userAvatarEditor).toHaveAttribute('src');
});
await test.step('expect set image from url', async () => {
await poAccountProfile.inputAvatarLink.fill('https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50');

test('should display a skeleton if the image url is not valid', async () => {
await poAccountProfile.inputAvatarLink.fill('https://invalidUrl');
await poAccountProfile.btnSetAvatarLink.click();

await poAccountProfile.btnSubmit.click();
await expect(page.locator('.rcx-toastbar.rcx-toastbar--success').first()).toBeVisible();
await expect(poAccountProfile.userAvatarEditor).not.toHaveAttribute('src');
});
});
})
});

test.describe('Security', () => {
Expand Down
4 changes: 4 additions & 0 deletions apps/meteor/tests/e2e/page-objects/account-profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ export class AccountProfile {
return this.page.locator('.avatar-file-input');
}

get userAvatarEditor(): Locator {
return this.page.locator('[data-qa-id="UserAvatarEditor"]');
}

get emailTextInput(): Locator {
return this.page.locator('//label[contains(text(), "Email")]/..//input');
}
Expand Down

0 comments on commit 61a655f

Please sign in to comment.