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
41 changes: 23 additions & 18 deletions src/components/OwnerMessage/OwnerMessage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ function OwnerMessage({
const [modalWrongPictureFormatWarning, setModalWrongPictureFormatWarning] = useState(false);

const canEditHeaderMessage = dispatch(hasPermission('editHeaderMessage'));

const isImage = /;base64/g;
const isImageMessage = value => typeof value === 'string' && value.includes(';base64');

function toggle() {
setModal(!modal);
Expand Down Expand Up @@ -116,14 +115,14 @@ function OwnerMessage({
}

function getContent(messages) {
if (isImage.test(messages)) {
if (isImageMessage(messages)) {
return <img src={messages} alt="" className={styles.ownerMessageImg} />;
}
return <span className={styles.message}>{messages}</span>;
}

function getHistoryContent(messages) {
if (isImage.test(messages)) {
if (isImageMessage(messages)) {
return <img src={messages} alt="" className={styles.ownerMessageImg} />;
}
return <span>{messages}</span>;
Expand Down Expand Up @@ -165,6 +164,7 @@ function OwnerMessage({
const headerBg = darkMode ? 'bg-space-cadet' : '';
const bodyBg = darkMode ? 'bg-yinmn-blue' : '';
const boxStyling = darkMode ? boxStyleDark : boxStyle;
const hasSelectedImage = isImageMessage(message);

return (
<div className={styles.messageContainer}>
Expand Down Expand Up @@ -250,20 +250,25 @@ function OwnerMessage({
disabled={disableTextInput}
className={styles.inputs}
/>
<p className="paragraph" style={{ marginTop: '1rem' }}>
Or upload a picture:
</p>
<span style={{ marginTop: '-1.25rem', marginBottom: '1rem', fontSize: '.8rem' }}>
(max size 1000 x 400 pixels and 100 KB)
</span>
<Input
id="image"
name="file"
type="file"
label="Choose Image"
onChange={event => handleImageUpload(event)}
className={styles.inputs}
/>
{!hasSelectedImage && (
<>
<p className="paragraph" style={{ marginTop: '1rem' }}>
Or upload a picture:
</p>
<span style={{ marginTop: '-1.25rem', marginBottom: '1rem', fontSize: '.8rem' }}>
(max size 1000 x 400 pixels and 100 KB)
</span>
<Input
id="image"
name="file"
type="file"
label="Choose Image"
aria-label="Choose owner message image"
onChange={event => handleImageUpload(event)}
className={styles.inputs}
/>
</>
)}
</ModalBody>

<ModalFooter
Expand Down
129 changes: 67 additions & 62 deletions src/components/OwnerMessage/__tests__/OwnerMessage.test.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { render, screen } from '@testing-library/react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { Provider } from 'react-redux';
import { configureStore } from 'redux-mock-store';
import thunk from 'redux-thunk';
Expand All @@ -12,94 +12,99 @@
describe('OwnerMessage Component', () => {
const middlewares = [thunk];
const mockStore = configureStore(middlewares);

it('should render without errors', () => {
const initialState = {
auth: {
user: {
role: 'Owner',
},
const baseState = {
auth: {
user: {
role: 'Owner',
},
ownerMessage: {
message: 'Sample Message',
standardMessage: 'Sample Standard Message',
},
theme: {
darkMode: false,
},
ownerMessage: {
message: 'Sample Message',
standardMessage: 'Sample Standard Message',
history: {
data: [],
pagination: {
page: 1,
totalPages: 1,
},
},
};
},
theme: {
darkMode: false,
},
};

// Create a mock store with initial state
function renderComponent(initialState = baseState) {
const store = mockStore(initialState);

// Mock the action creators
store.dispatch = vi.fn();

// Render with Provider
render(
<Provider store={store}>
<OwnerMessage />
</Provider>,
);

// Basic assertion to check if the component rendered
return store;
}

it('should render without errors', () => {
renderComponent();

expect(screen.getByText('Sample Message')).toBeInTheDocument();
});

it('should display standard message when no owner message exists', () => {
const initialState = {
auth: {
user: {
role: 'Owner',
},
},
renderComponent({
...baseState,
ownerMessage: {
...baseState.ownerMessage,
message: null,
standardMessage: 'Sample Standard Message',
},
theme: {
darkMode: false,
},
};

const store = mockStore(initialState);
store.dispatch = vi.fn();

render(
<Provider store={store}>
<OwnerMessage />
</Provider>,
);
});

expect(screen.getByText('Sample Standard Message')).toBeInTheDocument();
});

it('should show edit and delete buttons for owner role', () => {
const initialState = {
auth: {
user: {
role: 'Owner',
},
},
ownerMessage: {
message: 'Sample Message',
standardMessage: 'Sample Standard Message',
},
theme: {
darkMode: false,
renderComponent();

expect(screen.getByTitle('Edit this header')).toBeInTheDocument();
expect(screen.getByTitle('Click to restore header to standard message')).toBeInTheDocument();
});

it('hides the image upload controls after a photo is selected', async () => {
const originalFileReader = global.FileReader;

Check warning on line 76 in src/components/OwnerMessage/__tests__/OwnerMessage.test.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer `globalThis` over `global`.

See more on https://sonarcloud.io/project/issues?id=OneCommunityGlobal_HighestGoodNetworkApp&issues=AZ2e3DFTxD0pevEjKF0V&open=AZ2e3DFTxD0pevEjKF0V&pullRequest=5169

class MockFileReader {
onloadend = null;

readAsDataURL() {
this.result = 'data:image/png;base64,mock-image-payload';
queueMicrotask(() => {
this.onloadend?.();
});
}
}

global.FileReader = MockFileReader;

Check warning on line 89 in src/components/OwnerMessage/__tests__/OwnerMessage.test.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer `globalThis` over `global`.

See more on https://sonarcloud.io/project/issues?id=OneCommunityGlobal_HighestGoodNetworkApp&issues=AZ2e3DFTxD0pevEjKF0W&open=AZ2e3DFTxD0pevEjKF0W&pullRequest=5169

renderComponent();

fireEvent.click(screen.getByLabelText('Edit header message'));
expect(screen.getByText('Or upload a picture:')).toBeInTheDocument();

fireEvent.change(screen.getByLabelText('Choose owner message image'), {
target: {
files: [new File(['mock'], 'owner-message.png', { type: 'image/png' })],
},
};
});

const store = mockStore(initialState);
store.dispatch = vi.fn();
await waitFor(() => {
expect(screen.queryByText('Or upload a picture:')).not.toBeInTheDocument();
});

render(
<Provider store={store}>
<OwnerMessage />
</Provider>,
);
expect(screen.queryByLabelText('Choose owner message image')).not.toBeInTheDocument();

expect(screen.getByTitle('Edit this header')).toBeInTheDocument();
expect(screen.getByTitle('Click to restore header to standard message')).toBeInTheDocument();
global.FileReader = originalFileReader;

Check warning on line 108 in src/components/OwnerMessage/__tests__/OwnerMessage.test.jsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer `globalThis` over `global`.

See more on https://sonarcloud.io/project/issues?id=OneCommunityGlobal_HighestGoodNetworkApp&issues=AZ2e3DFTxD0pevEjKF0X&open=AZ2e3DFTxD0pevEjKF0X&pullRequest=5169
});
});
Loading