Skip to content
Open
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
99 changes: 0 additions & 99 deletions src/app/(protected)/account/profile/_components/ProfileMain.tsx

This file was deleted.

16 changes: 2 additions & 14 deletions src/app/(protected)/account/profile/page.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
'use client';

import { Container, Row } from 'react-bootstrap';
import { useTitle } from '@/hooks/useTitle';
import ProfileMain from './_components/ProfileMain';
import ProfileMain from 'module/protected/account/profile/ProfileMain';

const Profile = () => {
useTitle('Profile - BeeQuant');

return (
<Container>
<Row>
<ProfileMain />
</Row>
</Container>
);
return <ProfileMain />;
};
export default Profile;
3 changes: 0 additions & 3 deletions src/app/(protected)/crypto/exchange/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
'use client';

import { Col, Container, Row } from 'react-bootstrap';
import { useTitle } from '@/hooks/useTitle';

const CryptoExchanges = () => {
useTitle('Exchanges - BeeQuant');

return (
<Container>
<Row>
Expand Down
6 changes: 3 additions & 3 deletions src/graphql/codegen/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const documents = {
types.LoginDocument,
'\n mutation Register($input: CreateUserInput!) {\n register(input: $input) {\n code\n message\n data\n }\n }\n':
types.RegisterDocument,
'\n query getUserInfo {\n getUserInfo {\n id\n displayName\n }\n }\n':
'\n query getUserInfo {\n getUserInfo {\n id\n displayName\n email\n ref\n }\n }\n':
types.GetUserInfoDocument,
'\n query getUserById($id: String!) {\n getUserById(id: $id) {\n id\n email\n realName\n displayName\n mobile\n }\n }\n':
types.GetUserByIdDocument,
Expand Down Expand Up @@ -55,8 +55,8 @@ export function gql(
* The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function gql(
source: '\n query getUserInfo {\n getUserInfo {\n id\n displayName\n }\n }\n'
): (typeof documents)['\n query getUserInfo {\n getUserInfo {\n id\n displayName\n }\n }\n'];
source: '\n query getUserInfo {\n getUserInfo {\n id\n displayName\n email\n ref\n }\n }\n'
): (typeof documents)['\n query getUserInfo {\n getUserInfo {\n id\n displayName\n email\n ref\n }\n }\n'];
/**
* The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
Expand Down
10 changes: 9 additions & 1 deletion src/graphql/codegen/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,13 @@ export type GetUserInfoQueryVariables = Exact<{ [key: string]: never }>;

export type GetUserInfoQuery = {
__typename?: 'Query';
getUserInfo: { __typename?: 'UserType'; id: string; displayName: string };
getUserInfo: {
__typename?: 'UserType';
id: string;
displayName: string;
email: string;
ref: string;
};
};

export type GetUserByIdQueryVariables = Exact<{
Expand Down Expand Up @@ -375,6 +381,8 @@ export const GetUserInfoDocument = {
selections: [
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
{ kind: 'Field', name: { kind: 'Name', value: 'displayName' } },
{ kind: 'Field', name: { kind: 'Name', value: 'email' } },
{ kind: 'Field', name: { kind: 'Name', value: 'ref' } },
],
},
},
Expand Down
2 changes: 2 additions & 0 deletions src/graphql/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export const GET_USER = gql(`
getUserInfo {
id
displayName
email
ref
}
}
`);
Expand Down
134 changes: 134 additions & 0 deletions src/module/protected/account/profile/ProfileMain.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';
import { GET_USER, UPDATE_USER } from '@/graphql/user';
import { AUTH_TOKEN } from '@/shared/constants/storage';
import ProfileMain from './ProfileMain';

const mocks = [
{
request: {
query: GET_USER,
},
result: {
data: {
getUserInfo: {
id: '1332332',
email: 'test@example.com',
ref: 'ref123',
displayName: 'Test User',
},
},
},
},
{
request: {
query: UPDATE_USER,
variables: { id: '1332332', input: { displayName: 'Updated User' } },
},
result: {
data: {
updateUser: {
id: '1332332',
displayName: 'Updated User',
},
},
},
},
];

beforeEach(() => {
localStorage.setItem(AUTH_TOKEN, 'mock-token');
});

test('renders profile information', async () => {
render(
<MockedProvider mocks={mocks} addTypename={false}>
<ProfileMain />
</MockedProvider>
);

expect(screen.getByText('Loading...')).toBeInTheDocument();

await waitFor(() => {
expect(screen.getByText('Profile')).toBeInTheDocument();
});

expect(screen.getByDisplayValue('Test User')).toBeInTheDocument();
expect(screen.getByText('test@example.com')).toBeInTheDocument();
expect(screen.getByText('ref123')).toBeInTheDocument();
});

test('updates display name-valid', async () => {
render(
<MockedProvider mocks={mocks} addTypename={false}>
<ProfileMain />
</MockedProvider>
);

await waitFor(() => {
expect(screen.getByText('Profile')).toBeInTheDocument();
});

const input = screen.getByDisplayValue('Test User');
fireEvent.change(input, { target: { value: 'Updated User' } });
const button = screen.getByText('Submit');
fireEvent.click(button);

await waitFor(() => {
expect(screen.getByDisplayValue('Updated User')).toBeInTheDocument();
});
});

test('display name validation - minimum length', async () => {
render(
<MockedProvider mocks={mocks} addTypename={false}>
<ProfileMain />
</MockedProvider>
);

const input = await screen.findByDisplayValue('Test User');
fireEvent.change(input, { target: { value: 'Abc' } });
const button = screen.getByText('Submit');
fireEvent.click(button);

const errorMessage = await screen.findByText(
'Display name must be 4-15 characters long and contain only letters, numbers, hyphens, and underscores.'
);
expect(errorMessage).toBeInTheDocument();
});

test('display name validation - maximum length', async () => {
render(
<MockedProvider mocks={mocks} addTypename={false}>
<ProfileMain />
</MockedProvider>
);

const input = await screen.findByDisplayValue('Test User');
fireEvent.change(input, { target: { value: 'ThisIsAVeryLongDisplayName1231231231' } });
const button = screen.getByText('Submit');
fireEvent.click(button);

const errorMessage = await screen.findByText(
'Display name must be 4-15 characters long and contain only letters, numbers, hyphens, and underscores.'
);
expect(errorMessage).toBeInTheDocument();
});

test('display name validation - invalid characters', async () => {
render(
<MockedProvider mocks={mocks} addTypename={false}>
<ProfileMain />
</MockedProvider>
);

const input = await screen.findByDisplayValue('Test User');
fireEvent.change(input, { target: { value: 'Invalid!' } });
const button = screen.getByText('Submit');
fireEvent.click(button);

const errorMessage = await screen.findByText(
'Display name must be 4-15 characters long and contain only letters, numbers, hyphens, and underscores.'
);
expect(errorMessage).toBeInTheDocument();
});
Loading