Skip to content
Merged
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 @@ -107,9 +107,11 @@ export const getUserPath = (
username: string | undefined,
userId: string | undefined,
path: string,
isPreviewMode?: boolean,
): string => {
const userIdentifier = username || userId;
return `/${userIdentifier}${path}`;
const query = isPreviewMode ? '?preview=true' : '';
return `/${userIdentifier}${path}${query}`;
};

export const renderEmptyScreen = (
Expand Down
2 changes: 2 additions & 0 deletions packages/shared/src/features/profile/components/Activity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const Activity = ({ user }: ActivityProps): ReactElement | null => {
<ActivityPostsTab
userId={userId}
isSameUser={isOwner}
isPreviewMode={isPreviewMode}
userName={user?.name ?? 'User'}
user={user}
selectedTab={selectedTab}
Expand All @@ -56,6 +57,7 @@ export const Activity = ({ user }: ActivityProps): ReactElement | null => {
<ActivityUpvotedTab
userId={userId}
isSameUser={isOwner}
isPreviewMode={isPreviewMode}
userName={user?.name ?? 'User'}
user={user}
selectedTab={selectedTab}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ import { HorizontalFeedWithContext } from './HorizontalFeedWithContext';
export const ActivityPostsTab = ({
userId,
isSameUser,
isPreviewMode,
userName,
user,
selectedTab,
onTabClick,
}: {
userId: string;
isSameUser: boolean;
isPreviewMode: boolean;
userName: string;
user: PublicProfile;
selectedTab: string;
Expand Down Expand Up @@ -82,6 +84,7 @@ export const ActivityPostsTab = ({
user?.username,
user?.id,
activityTabs[ActivityTabIndex.Posts].path,
isPreviewMode,
)}
passHref
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ export const ActivityRepliesTab = ({
user?.username,
user?.id,
activityTabs[ActivityTabIndex.Replies].path,
isPreviewMode,
)}
passHref
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ import { HorizontalFeedWithContext } from './HorizontalFeedWithContext';
export const ActivityUpvotedTab = ({
userId,
isSameUser,
isPreviewMode,
userName,
user,
selectedTab,
onTabClick,
}: {
userId: string;
isSameUser: boolean;
isPreviewMode: boolean;
userName: string;
user: PublicProfile;
selectedTab: string;
Expand Down Expand Up @@ -82,6 +84,7 @@ export const ActivityUpvotedTab = ({
user?.username,
user?.id,
activityTabs[ActivityTabIndex.Upvoted].path,
isPreviewMode,
)}
passHref
>
Expand Down
29 changes: 29 additions & 0 deletions packages/webapp/__tests__/ProfilePostsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,32 @@ it('should show different empty screen when visiting your profile', async () =>
const el = await screen.findByText('New post');
expect(el).toBeInTheDocument();
});

it('should not offer the owner a new post CTA in preview mode', async () => {
jest.mocked(useRouter).mockImplementation(
() =>
({
pathname: '/[userId]/posts',
query: { userId: 'dailydotdev', preview: 'true' },
isFallback: false,
} as unknown as NextRouter),
);
renderComponent(
[
createFeedMock({
pageInfo: {
hasNextPage: true,
endCursor: '',
},
edges: [],
}),
],
{},
defaultProfile as unknown as LoggedUser,
);
await waitForNock();
expect(
await screen.findByText("Daily Dev hasn't posted yet"),
).toBeInTheDocument();
expect(screen.queryByText('New post')).not.toBeInTheDocument();
});
58 changes: 53 additions & 5 deletions packages/webapp/__tests__/ProfileRepliesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { render, screen } from '@testing-library/react';
import type {
LoggedUser,
PublicProfile,
UserSocialLink,
} from '@dailydotdev/shared/src/lib/user';
import nock from 'nock';
import { QueryClient } from '@tanstack/react-query';
Expand All @@ -20,11 +21,26 @@ import type {
Author,
} from '@dailydotdev/shared/src/graphql/comments';
import { USER_COMMENTS_QUERY } from '@dailydotdev/shared/src/graphql/comments';
import type { NextRouter } from 'next/router';
import { useRouter } from 'next/router';
import ProfilePage from '../pages/[userId]/replies';

jest.mock('next/router', () => ({
useRouter: jest.fn(),
}));

beforeEach(() => {
nock.cleanAll();
jest.clearAllMocks();

jest.mocked(useRouter).mockImplementation(
() =>
({
pathname: '/',
query: {},
isFallback: false,
} as unknown as NextRouter),
);
});

const defaultProfile: PublicProfile = {
Expand All @@ -37,10 +53,12 @@ const defaultProfile: PublicProfile = {
cover: 'https://daily.dev/cover.png',
bio: 'The best company!',
createdAt: '2020-08-26T13:04:35.000Z',
twitter: 'dailydotdev',
github: 'dailydotdev',
hashnode: 'dailydotdev',
portfolio: 'https://daily.dev/?key=vaue',
socialLinks: [
{ platform: 'twitter', url: 'https://x.com/dailydotdev' },
{ platform: 'github', url: 'https://github.com/dailydotdev' },
{ platform: 'hashnode', url: 'https://dailydotdev.hashnode.dev' },
{ platform: 'portfolio', url: 'https://daily.dev/?key=vaue' },
] as UserSocialLink[],
permalink: 'https://daily.dev/dailydotdev',
};

Expand All @@ -56,6 +74,7 @@ export const defaultCommentsPage: Connection<Comment> = {
createdAt: '2020-07-26T13:04:35.000Z',
content: 'My comment',
numUpvotes: 50,
numAwards: 0,
id: 'c1',
contentHtml: 'My comment',
post: defaultPost,
Expand Down Expand Up @@ -93,7 +112,7 @@ const renderComponent = (
mocks.forEach(mockGraphQL);
return render(
<TestBootProvider client={client} auth={{ user }}>
<ProfilePage user={{ ...defaultProfile, ...profile }} />
<ProfilePage user={{ ...defaultProfile, ...profile }} noindex={false} />
</TestBootProvider>,
);
};
Expand Down Expand Up @@ -145,3 +164,32 @@ it('should show different empty screen when visiting your profile', async () =>
const el = await screen.findByText('Explore posts');
expect(el).toBeInTheDocument();
});

it('should show the visitor empty screen to the owner in preview mode', async () => {
jest.mocked(useRouter).mockImplementation(
() =>
({
pathname: '/[userId]/replies',
query: { userId: 'dailydotdev', preview: 'true' },
isFallback: false,
} as unknown as NextRouter),
);
renderComponent(
[
createCommentsMock({
pageInfo: {
hasNextPage: true,
endCursor: '',
},
edges: [],
}),
],
{},
defaultProfile as unknown as LoggedUser,
);
await waitForNock();
expect(
await screen.findByText("Daily Dev hasn't replied to any post yet"),
).toBeInTheDocument();
expect(screen.queryByText('Explore posts')).not.toBeInTheDocument();
});
29 changes: 29 additions & 0 deletions packages/webapp/__tests__/ProfileUpvotedPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,32 @@ it('should show different empty screen when visiting your profile', async () =>
const el = await screen.findByText('Explore posts');
expect(el).toBeInTheDocument();
});

it('should show the visitor empty screen to the owner in preview mode', async () => {
jest.mocked(useRouter).mockImplementation(
() =>
({
pathname: '/[userId]/upvoted',
query: { userId: 'dailydotdev', preview: 'true' },
isFallback: false,
} as unknown as NextRouter),
);
renderComponent(
[
createFeedMock({
pageInfo: {
hasNextPage: true,
endCursor: '',
},
edges: [],
}),
],
{},
defaultProfile as unknown as LoggedUser,
);
await waitForNock();
expect(
await screen.findByText("Daily Dev hasn't upvoted yet"),
).toBeInTheDocument();
expect(screen.queryByText('Explore posts')).not.toBeInTheDocument();
});
9 changes: 4 additions & 5 deletions packages/webapp/pages/[userId]/posts.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ReactElement } from 'react';
import React, { useContext } from 'react';
import React from 'react';
import { link } from '@dailydotdev/shared/src/lib/links';
import { AUTHOR_FEED_QUERY } from '@dailydotdev/shared/src/graphql/feed';
import type { FeedProps } from '@dailydotdev/shared/src/components/Feed';
Expand All @@ -8,7 +8,7 @@ import { OtherFeedPage } from '@dailydotdev/shared/src/lib/query';
import { MyProfileEmptyScreen } from '@dailydotdev/shared/src/components/profile/MyProfileEmptyScreen';
import { ProfileEmptyScreen } from '@dailydotdev/shared/src/components/profile/ProfileEmptyScreen';
import { cloudinaryCharmNoPosts } from '@dailydotdev/shared/src/lib/image';
import AuthContext from '@dailydotdev/shared/src/contexts/AuthContext';
import { useProfilePreview } from '@dailydotdev/shared/src/hooks/profile/useProfilePreview';
import { useFeedLayout } from '@dailydotdev/shared/src/hooks';
import classNames from 'classnames';
import { NextSeo } from 'next-seo';
Expand All @@ -35,14 +35,13 @@ const ProfilePostsPage = ({
user,
noindex,
}: ProfileLayoutProps): ReactElement | null => {
const { user: loggedUser } = useContext(AuthContext);
const { isOwner } = useProfilePreview(user);
const { shouldUseListFeedLayout } = useFeedLayout();

if (!user) {
return null;
}

const isSameUser = loggedUser?.id === user.id;
const userId = user.id;
const feedProps: FeedProps<unknown> = {
feedName: OtherFeedPage.Author,
Expand All @@ -52,7 +51,7 @@ const ProfilePostsPage = ({
userId,
},
disableAds: true,
emptyScreen: isSameUser ? (
emptyScreen: isOwner ? (
<MyProfileEmptyScreen
className="items-center px-4 py-6 text-center tablet:px-6"
image={cloudinaryCharmNoPosts}
Expand Down
9 changes: 4 additions & 5 deletions packages/webapp/pages/[userId]/replies.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { ReactElement } from 'react';
import React, { useContext } from 'react';
import React from 'react';
import { USER_COMMENTS_QUERY } from '@dailydotdev/shared/src/graphql/comments';
import { Origin } from '@dailydotdev/shared/src/lib/log';
import {
generateQueryKey,
RequestKey,
} from '@dailydotdev/shared/src/lib/query';
import AuthContext from '@dailydotdev/shared/src/contexts/AuthContext';
import { useProfilePreview } from '@dailydotdev/shared/src/hooks/profile/useProfilePreview';
import { MyProfileEmptyScreen } from '@dailydotdev/shared/src/components/profile/MyProfileEmptyScreen';
import { ProfileEmptyScreen } from '@dailydotdev/shared/src/components/profile/ProfileEmptyScreen';
import { cloudinaryCharmEmptyProfile } from '@dailydotdev/shared/src/lib/image';
Expand Down Expand Up @@ -42,16 +42,15 @@ const ProfileCommentsPage = ({
user,
noindex,
}: ProfileLayoutProps): ReactElement | null => {
const { user: loggedUser } = useContext(AuthContext);
const { isOwner } = useProfilePreview(user);

if (!user) {
return null;
}

const isSameUser = loggedUser?.id === user.id;
const userId = user.id;

const emptyScreen = isSameUser ? (
const emptyScreen = isOwner ? (
<MyProfileEmptyScreen
className="items-center px-4 py-6 text-center tablet:px-6"
image={cloudinaryCharmEmptyProfile}
Expand Down
9 changes: 4 additions & 5 deletions packages/webapp/pages/[userId]/upvoted.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { ReactElement } from 'react';
import React, { useContext } from 'react';
import React from 'react';
import type { FeedProps } from '@dailydotdev/shared/src/components/Feed';
import Feed from '@dailydotdev/shared/src/components/Feed';
import { OtherFeedPage } from '@dailydotdev/shared/src/lib/query';
import { USER_UPVOTED_FEED_QUERY } from '@dailydotdev/shared/src/graphql/feed';
import { MyProfileEmptyScreen } from '@dailydotdev/shared/src/components/profile/MyProfileEmptyScreen';
import { ProfileEmptyScreen } from '@dailydotdev/shared/src/components/profile/ProfileEmptyScreen';
import { cloudinaryCharmEmptyProfile } from '@dailydotdev/shared/src/lib/image';
import AuthContext from '@dailydotdev/shared/src/contexts/AuthContext';
import { useProfilePreview } from '@dailydotdev/shared/src/hooks/profile/useProfilePreview';
import { useFeedLayout } from '@dailydotdev/shared/src/hooks';
import classNames from 'classnames';
import type { NextSeoProps } from 'next-seo/lib/types';
Expand All @@ -34,14 +34,13 @@ const ProfileUpvotedPage = ({
user,
noindex,
}: ProfileLayoutProps): ReactElement | null => {
const { user: loggedUser } = useContext(AuthContext);
const { isOwner } = useProfilePreview(user);
const { shouldUseListFeedLayout } = useFeedLayout();

if (!user) {
return null;
}

const isSameUser = loggedUser?.id === user.id;
const userId = user.id;
const feedProps: FeedProps<unknown> = {
feedName: OtherFeedPage.UserUpvoted,
Expand All @@ -51,7 +50,7 @@ const ProfileUpvotedPage = ({
userId,
},
disableAds: true,
emptyScreen: isSameUser ? (
emptyScreen: isOwner ? (
<MyProfileEmptyScreen
className="items-center px-4 py-6 text-center tablet:px-6"
image={cloudinaryCharmEmptyProfile}
Expand Down
Loading