Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/show task updater info #1281

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@ beforeEach(() => {
});

describe('ProgressUpdateCard Component', () => {
it('should check if the onCardClick function is called when user click on card', () => {
renderWithRouter(
<Provider store={store()}>
<ProgressUpdateCard data={mockGetTaskProgress.data[2]} />
</Provider>
);
const progressUpdateCardContainer = screen.getByTestId(
'progress-update-card-container'
);
fireEvent.click(progressUpdateCardContainer);
expect(progressUpdateCardContainer).toHaveClass(
'progress-update-card__container expand'
);
});

it('should render completed section string as title in card', () => {
renderWithRouter(
<Provider store={store()}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import moment from 'moment';
import { MouseEvent } from 'react';
import { Provider } from 'react-redux';
import { fireEvent, screen } from '@testing-library/react';

import { useRouter } from 'next/router';
import { mockGetTaskProgress } from '../../../../../__mocks__/db/progresses';
import { renderWithRouter } from '@/test_utils/createMockRouter';
import { readMoreFormatter } from '@/utils/common';
import { store } from '@/app/store';
import { DEFAULT_AVATAR, USER_MANAGEMENT_URL } from '@/constants/url';

import {
ProgressUpdateCardPresentationProps,
Expand All @@ -17,6 +18,8 @@ import ProgressUpdateCardPresentation from '@/components/taskDetails/ProgressUpd

let initialProps: ProgressUpdateCardPresentationProps;
const titleToShow = mockGetTaskProgress.data[1].completed;
const username = 'mock-user-name';
const userProfileImageUrl = 'random-profile-pic-url';
const momentDate = moment(mockGetTaskProgress.data[2].createdAt);
const fullDate = momentDate.format('DD-MM-YY');
const time = momentDate.format('hh:mmA');
Expand All @@ -29,6 +32,9 @@ let mockedOnMoreOrLessButtonClick: jest.Mock<
[React.MouseEvent<HTMLElement>]
>;
let mockedOnCardClick: jest.Mock<void, [MouseEvent<HTMLElement>]>;
jest.mock('next/router', () => ({
useRouter: jest.fn(),
}));
const charactersToShow = 70;
const dataToShowState = [
{
Expand Down Expand Up @@ -114,6 +120,8 @@ describe('ProgressUpdateCardPresentation Component', () => {
jest.fn<void, [React.MouseEvent<HTMLElement>]>();
mockedOnCardClick = jest.fn<void, [React.MouseEvent<HTMLElement>]>();
initialProps = {
username: username,
userProfileImageUrl: userProfileImageUrl,
titleToShow: titleToShow,
isExpanded: false,
dateInAgoFormat: dateInAgoFormat,
Expand All @@ -123,7 +131,76 @@ describe('ProgressUpdateCardPresentation Component', () => {
onCardClick: mockedOnCardClick,
};
});

it('should rotate the angle icon when expanded', () => {
(useRouter as jest.Mock).mockReturnValue({
query: { dev: 'false' },
});
AnujChhikara marked this conversation as resolved.
Show resolved Hide resolved
const props = { ...initialProps, isExpanded: true };
renderWithRouter(
AnujChhikara marked this conversation as resolved.
Show resolved Hide resolved
<Provider store={store()}>
<ProgressUpdateCardPresentation {...props} />
</Provider>
);
const angleIcon = screen.getByTestId('progress-update-card-angle-icon');
expect(angleIcon).toHaveStyle('transform: rotate(90deg)');
});
it('should have respective classes on date container and date text', () => {
(useRouter as jest.Mock).mockReturnValue({
query: { dev: 'false' },
});
renderWithRouter(
<Provider store={store()}>
<ProgressUpdateCardPresentation {...initialProps} />
</Provider>
);
const dateContainer = screen.getByTestId('progress-update-card-date');
const dateText = screen.getByText(dateInAgoFormat);

expect(dateContainer).toHaveClass(
'progress-update-card__date-container'
);
expect(dateText).toHaveClass('progress-update-card__date-text');
});

it('should not rotate the angle icon when not expanded', () => {
(useRouter as jest.Mock).mockReturnValue({
query: { dev: 'false' },
});
const props = { ...initialProps, isExpanded: false };
renderWithRouter(
<Provider store={store()}>
<ProgressUpdateCardPresentation {...props} />
</Provider>
);
const angleIcon = screen.getByTestId('progress-update-card-angle-icon');
expect(angleIcon).toHaveStyle('transform: none');
});

it('should prevent event propagation when clicking on the date container', () => {
(useRouter as jest.Mock).mockReturnValue({
query: { dev: 'false' },
});
renderWithRouter(
<Provider store={store()}>
<ProgressUpdateCardPresentation {...initialProps} />
</Provider>
);

const dateContainer = screen.getByTestId('progress-update-card-date');
const stopPropagationMock = jest.fn();
dateContainer.addEventListener(
'click',
(event) => (event.stopPropagation = stopPropagationMock)
);
fireEvent.click(dateContainer);
expect(stopPropagationMock).toHaveBeenCalled();
});

it('should render completed section string as title in card', () => {
(useRouter as jest.Mock).mockReturnValue({
query: { dev: 'false' },
});
renderWithRouter(
<Provider store={store()}>
<ProgressUpdateCardPresentation {...initialProps} />
Expand All @@ -135,6 +212,9 @@ describe('ProgressUpdateCardPresentation Component', () => {
);
});
it('should render date with ago format', () => {
(useRouter as jest.Mock).mockReturnValue({
query: { dev: 'false' },
});
renderWithRouter(
<Provider store={store()}>
<ProgressUpdateCardPresentation {...initialProps} />
Expand All @@ -144,6 +224,106 @@ describe('ProgressUpdateCardPresentation Component', () => {
expect(date).toHaveTextContent(dateInAgoFormat);
});

it('should render the name and profile picture of the updater', () => {
(useRouter as jest.Mock).mockReturnValue({
query: { dev: 'true' },
});
const props: ProgressUpdateCardPresentationProps = {
...initialProps,
};
renderWithRouter(
<Provider store={store()}>
<ProgressUpdateCardPresentation {...props} />
</Provider>
);
const usernameElement = screen.getByTestId(
'progress-update-card-user-info-container'
);
expect(usernameElement).toBeInTheDocument();
expect(usernameElement.textContent).toContain('mock-user-name');
const userProfileImageUrlElement = screen.getByTestId(
'progress-update-card-profile-picture'
);

expect(userProfileImageUrlElement).toBeInTheDocument();
expect(userProfileImageUrlElement).toHaveAttribute(
'src',
userProfileImageUrl
);
expect(userProfileImageUrlElement).toHaveAttribute('alt', 'Avatar');
});
it('should display the default avatar if profile url is empty', () => {
(useRouter as jest.Mock).mockReturnValue({
query: { dev: 'true' },
});
const props: ProgressUpdateCardPresentationProps = {
...initialProps,
userProfileImageUrl: '',
};
renderWithRouter(
<Provider store={store()}>
<ProgressUpdateCardPresentation {...props} />
</Provider>
);
const userProfileImageUrlElement = screen.getByTestId(
'progress-update-card-profile-picture'
);

expect(userProfileImageUrlElement).toBeInTheDocument();
expect(userProfileImageUrlElement).toHaveAttribute(
'src',
DEFAULT_AVATAR
);
});
it('should render the updater name as a link with the correct href', () => {
(useRouter as jest.Mock).mockReturnValue({
query: { dev: 'true' },
});
const props: ProgressUpdateCardPresentationProps = {
...initialProps,
};
renderWithRouter(
<Provider store={store()}>
<ProgressUpdateCardPresentation {...props} />
</Provider>
);

const linkElement = screen
.getByTestId('progress-update-card-user-info-container')
.querySelector('a');
expect(linkElement).toBeInTheDocument();
expect(linkElement).toHaveAttribute(
'href',
`${USER_MANAGEMENT_URL}?username=${username}`
);
expect(linkElement?.textContent).toContain(username);
});
it('should prevent event propagation when clicking on the user info container', () => {
(useRouter as jest.Mock).mockReturnValue({
query: { dev: 'true' },
});

renderWithRouter(
<Provider store={store()}>
<ProgressUpdateCardPresentation {...initialProps} />
</Provider>
);

const userInfoContainer = screen.getByTestId(
'progress-update-card-user-info-container'
);

const stopPropagationMock = jest.fn();

userInfoContainer.addEventListener(
'click',
(event) => (event.stopPropagation = stopPropagationMock)
);

fireEvent.click(userInfoContainer);
expect(stopPropagationMock).toHaveBeenCalled();
});

it('should not render the tooltip when isToolisTooltipVisible is false', () => {
const props: ProgressUpdateCardPresentationProps = {
...initialProps,
Expand Down
9 changes: 9 additions & 0 deletions src/app/services/usersApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ type UsernameQueryArgs = {
searchString?: string;
size?: number;
};
type UserResponse = {
message: string;
user: userDataType;
};

export const usersApi = api.injectEndpoints({
endpoints: (build) => ({
Expand All @@ -39,6 +43,10 @@ export const usersApi = api.injectEndpoints({
query: ({ searchString }) => `/users?search=${searchString}`,
providesTags: ['Users'],
}),
getUserDetailsById: build.query<UserResponse, UsernameQueryArgs>({
query: ({ searchString }) => `/users?id=${searchString}`,
providesTags: ['Users'],
}),
}),
});

Expand All @@ -48,4 +56,5 @@ export const {
useGetUsersQuery,
useGetAllUsersByUsernameQuery,
useGetAllUsersQuery,
useGetUserDetailsByIdQuery,
} = usersApi;
2 changes: 1 addition & 1 deletion src/components/common/Tooltip/tooltip.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

.tooltip {
position: absolute;
width: 17rem;
width: 18rem;
// position - top, bottom, right, left will come from props for reusability
background-color: $theme-primary;
border: 1px solid $theme-primary;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, { MouseEvent, useState } from 'react';
import { readMoreFormatter } from '@/utils/common';
import { ProgressDetailsData } from '@/types/standup.type';
import LatestProgressUpdateCardPresentation from './LatestProgressUpdateCardPresentation';
import { useGetUserDetailsByIdQuery } from '@/app/services/usersApi';

type LatestProgressUpdateCardProps = {
data: ProgressDetailsData;
Expand All @@ -21,11 +22,17 @@ export default function LatestProgressUpdateCard({
data,
}: LatestProgressUpdateCardProps) {
const momentDate = moment(data?.createdAt);
const userId = data?.userId;
const { data: userData } = useGetUserDetailsByIdQuery({
searchString: userId,
});
const username = userData?.user?.username ?? '';
const userProfileImageUrl = userData?.user?.picture?.url ?? '';

const dateInAgoFormat = momentDate.fromNow();
const fullDate = momentDate.format('dddd, MMMM DD, YYYY, hh:mm A [GMT] Z');
const tooltipText = `Updated at ${fullDate}`;
const charactersToShow = 70;

const dataToShow = [
{
id: `completed-${data.id}`,
Expand Down Expand Up @@ -55,7 +62,6 @@ export default function LatestProgressUpdateCard({

const [dataToShowState, setDataToShowState] =
useState<ProgressUpdateDataToShow[]>(dataToShow);

function onMoreOrLessButtonClick(
e: MouseEvent<HTMLElement>,
clickedOnData: ProgressUpdateDataToShow
Expand All @@ -74,6 +80,8 @@ export default function LatestProgressUpdateCard({

return (
<LatestProgressUpdateCardPresentation
username={username}
userProfileImageUrl={userProfileImageUrl}
dataToShowState={dataToShowState}
tooltipText={tooltipText}
onMoreOrLessButtonClick={onMoreOrLessButtonClick}
Expand Down
Loading