diff --git a/frontend/app/components/profile/profile.module.css b/frontend/app/components/profile/profile.module.css
index 0fe1c0aa..45796a7d 100644
--- a/frontend/app/components/profile/profile.module.css
+++ b/frontend/app/components/profile/profile.module.css
@@ -67,6 +67,11 @@
padding: 0 16px 16px;
}
+.error {
+ font-size: 14px;
+ margin: 0 0 4px;
+}
+
.content::-webkit-scrollbar {
width: 10px;
}
@@ -101,6 +106,7 @@
.info {
max-width: 100%;
margin: 0;
+ padding-right: 8px;
overflow: hidden;
line-height: 1;
}
@@ -109,6 +115,7 @@
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
+ white-space: nowrap;
font-size: 16px;
font-weight: 700;
}
@@ -117,6 +124,7 @@
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
+ white-space: nowrap;
font-size: 12px;
color: var(--color13);
}
@@ -160,7 +168,7 @@
}
.preloader {
- margin: 0 auto 18px;
+ margin: 0 auto;
color: var(--color13);
}
diff --git a/frontend/app/components/profile/profile.spec.tsx b/frontend/app/components/profile/profile.spec.tsx
index 3f38c20b..f6fea318 100644
--- a/frontend/app/components/profile/profile.spec.tsx
+++ b/frontend/app/components/profile/profile.spec.tsx
@@ -1,6 +1,5 @@
import { h } from 'preact';
import '@testing-library/jest-dom';
-import { waitFor } from '@testing-library/preact';
import { render } from 'tests/utils';
import * as api from 'common/api';
@@ -43,48 +42,68 @@ const commentsStub = [commentStub, commentStub, commentStub];
describe('', () => {
it('should render preloader', () => {
jest.spyOn(pq, 'parseQuery').mockImplementation(() => ({ ...userParamsStub }));
- const { container } = render();
+ const { queryByLabelText, queryByRole } = render();
- expect(container.querySelector('[aria-label="Loading..."]')).toBeInTheDocument();
+ expect(queryByLabelText('Loading...')).toBeInTheDocument();
+ expect(queryByRole('button', { name: /retry/i })).not.toBeInTheDocument();
+ expect(queryByRole('heading', { name: /recent comments/i })).not.toBeInTheDocument();
+ });
+
+ it('should render error', async () => {
+ jest.spyOn(pq, 'parseQuery').mockImplementation(() => ({ ...userParamsStub }));
+ jest.spyOn(api, 'getUserComments').mockImplementation(async () => {
+ throw new Error('error');
+ });
+ const { queryByLabelText, queryByRole, findByRole } = render();
+
+ expect(await findByRole('button', { name: /retry/i })).toBeInTheDocument();
+ expect(queryByLabelText('Loading...')).not.toBeInTheDocument();
+ expect(queryByRole('heading', { name: /recent comments/i })).not.toBeInTheDocument();
});
it('should render without comments', async () => {
jest.spyOn(pq, 'parseQuery').mockImplementation(() => ({ ...userParamsStub }));
const getUserComments = jest.spyOn(api, 'getUserComments').mockImplementation(async () => ({ comments: [] }));
- const { getByText } = render();
+ const { findByText, queryByLabelText, queryByRole } = render();
- await waitFor(() => expect(getUserComments).toHaveBeenCalledWith('1'));
- await waitFor(() => expect(getByText("Don't have comments yet")).toBeInTheDocument());
+ expect(getUserComments).toHaveBeenCalledWith('1');
+ expect(await findByText("Don't have comments yet")).toBeInTheDocument();
+ expect(queryByLabelText('Loading...')).not.toBeInTheDocument();
+ expect(queryByRole('button', { name: /retry/i })).not.toBeInTheDocument();
});
it('should render user with comments', async () => {
jest.spyOn(pq, 'parseQuery').mockImplementation(() => userParamsStub);
jest.spyOn(api, 'getUserComments').mockImplementation(async () => ({ comments: commentsStub }));
- const { getByText } = render();
+ const { findByText, queryByLabelText, queryByRole } = render();
- await waitFor(() => expect(getByText('Recent comments')).toBeInTheDocument());
+ expect(await findByText('Recent comments')).toBeInTheDocument();
+ expect(queryByLabelText('Loading...')).not.toBeInTheDocument();
+ expect(queryByRole('button', { name: /retry/i })).not.toBeInTheDocument();
});
- it('shoud render current user without comments', async () => {
+ it('should render current user without comments', async () => {
jest.spyOn(pq, 'parseQuery').mockImplementation(() => ({ ...userParamsStub, current: '1' }));
+ jest.spyOn(api, 'getUserComments').mockImplementation(async () => ({ comments: [] }));
- const { getByText, getByTitle } = render();
+ const { getByText, getByTitle, findByText } = render();
expect(getByTitle('Sign Out')).toBeInTheDocument();
expect(getByText('Request my data removal')).toBeInTheDocument();
+ expect(await findByText("Don't have comments yet")).toBeInTheDocument();
});
- it('shoud render current user with comments', async () => {
+ it('should render current user with comments', async () => {
jest.spyOn(pq, 'parseQuery').mockImplementation(() => ({ ...userParamsStub, current: '1' }));
jest.spyOn(api, 'getUserComments').mockImplementation(async () => ({ comments: commentsStub }));
- const { getByText, getByTitle } = render();
+ const { findByText, queryByTitle, queryByText } = render();
- expect(getByTitle('Sign Out')).toBeInTheDocument();
- expect(getByText('Request my data removal')).toBeInTheDocument();
- await waitFor(() => expect(getByText('My recent comments')).toBeInTheDocument());
+ expect(queryByTitle('Sign Out')).toBeInTheDocument();
+ expect(queryByText('Request my data removal')).toBeInTheDocument();
+ expect(await findByText('My recent comments')).toBeInTheDocument();
});
it('should render user without footer', async () => {
diff --git a/frontend/app/components/profile/profile.tsx b/frontend/app/components/profile/profile.tsx
index 65e38133..53396c78 100644
--- a/frontend/app/components/profile/profile.tsx
+++ b/frontend/app/components/profile/profile.tsx
@@ -32,10 +32,27 @@ export function Profile() {
const intl = useIntl();
const rootRef = useRef(null);
const user = useMemo(() => parseQuery(), []);
+ const [isCommentsLoading, setIsCommentsLoading] = useState(false);
const [error, setError] = useState(false);
const [comments, setComments] = useState(null);
const [isSigningOut, setSigningOut] = useState(false);
+ async function fetchUserComments(userId: string) {
+ setIsCommentsLoading(true);
+ setError(false);
+ setComments(null);
+
+ try {
+ const { comments } = await getUserComments(userId);
+
+ setComments(comments);
+ } catch (err) {
+ setError(true);
+ } finally {
+ setIsCommentsLoading(false);
+ }
+ }
+
function handleClickClose() {
const rootElement = rootRef.current;
@@ -58,10 +75,12 @@ export function Profile() {
await signout();
}
+ function handleClickRetryCommentsRequest() {
+ fetchUserComments(user.id);
+ }
+
useEffect(() => {
- getUserComments(user.id)
- .then(({ comments }) => setComments(comments))
- .catch(() => setError(true));
+ fetchUserComments(user.id);
}, [user.id]);
useEffect(() => {
@@ -154,11 +173,17 @@ export function Profile() {
{error && (
-
-
-
+ <>
+
+
+
+
+ >
)}
- {comments === null ? : commentsJSX}
+ {isCommentsLoading && }
+ {comments !== null && commentsJSX}
{isCurrent ? (