Skip to content
Snippets Groups Projects
Commit dc89191f authored by Mateusz Bolewski's avatar Mateusz Bolewski
Browse files

Merge branch 'feat/context-menu' of...

Merge branch 'feat/context-menu' of ssh://gitlab.lcsb.uni.lu:8022/minerva/frontend into feat/molart-modal
parents 5c6f8a75 51305042
No related branches found
No related tags found
2 merge requests!223reset the pin numbers before search results are fetch (so the results will be...,!84feat: Molart modal
Pipeline #83788 failed
Showing
with 2805 additions and 1412 deletions
This diff is collapsed.
......@@ -9,3 +9,26 @@ global.ResizeObserver = jest.fn().mockImplementation(() => ({
}));
jest.mock('next/router', () => require('next-router-mock'));
const localStorageMock = (() => {
let store: {
[key: PropertyKey]: string;
} = {};
return {
getItem: jest.fn((key: PropertyKey) => store[key] || null),
setItem: jest.fn((key: PropertyKey, value: any) => {
store[key] = value.toString();
}),
removeItem: jest.fn((key: PropertyKey) => {
delete store[key];
}),
clear: jest.fn(() => {
store = {};
}),
};
})();
Object.defineProperty(global, 'localStorage', {
value: localStorageMock,
});
......@@ -7,6 +7,8 @@ import { searchedBioEntityElementUniProtIdSelector } from '@/redux/bioEntity/bio
import { openMolArtModalById } from '@/redux/modal/modal.slice';
import { closeContextMenu } from '@/redux/contextMenu/contextMenu.slice';
import { FIRST_ARRAY_ELEMENT, SECOND_ARRAY_ELEMENT } from '@/constants/common';
export const ContextMenu = (): React.ReactNode => {
const dispatch = useAppDispatch();
const { isOpen, coordinates } = useAppSelector(contextMenuSelector);
......@@ -31,8 +33,10 @@ export const ContextMenu = (): React.ReactNode => {
'absolute z-10 rounded-lg border border-[#DBD9D9] bg-white p-4',
isOpen ? '' : 'hidden',
)}
// eslint-disable-next-line no-magic-numbers
style={{ left: `${coordinates[0]}px`, top: `${coordinates[1]}px` }}
style={{
left: `${coordinates[FIRST_ARRAY_ELEMENT]}px`,
top: `${coordinates[SECOND_ARRAY_ELEMENT]}px`,
}}
>
<button
className={twMerge(
......
import React from 'react';
import { render, screen } from '@testing-library/react';
import { ToolkitStoreWithSingleSlice } from '@/utils/createStoreInstanceUsingSliceReducer';
import { CookieBannerState } from '@/redux/cookieBanner/cookieBanner.types';
import { getReduxWrapperUsingSliceReducer } from '@/utils/testing/getReduxWrapperUsingSliceReducer';
import cookieBannerReducer from '@/redux/cookieBanner/cookieBanner.slice';
import { act } from 'react-dom/test-utils';
import { CookieBanner } from './CookieBanner.component';
import {
USER_ACCEPTED_COOKIES_COOKIE_NAME,
USER_ACCEPTED_COOKIES_COOKIE_VALUE,
} from './CookieBanner.constants';
const renderComponent = (): { store: ToolkitStoreWithSingleSlice<CookieBannerState> } => {
const { Wrapper, store } = getReduxWrapperUsingSliceReducer('cookieBanner', cookieBannerReducer);
return (
render(
<Wrapper>
<CookieBanner />
</Wrapper>,
),
{
store,
}
);
};
describe('CookieBanner component', () => {
beforeEach(() => {
localStorage.clear();
});
it('renders cookie banner correctly first time', () => {
renderComponent();
expect(localStorage.getItem).toHaveBeenCalledWith(USER_ACCEPTED_COOKIES_COOKIE_NAME);
const button = screen.getByLabelText(/accept cookies/i);
expect(button).toBeInTheDocument();
});
it('hides the banner after accepting cookies', () => {
renderComponent();
const button = screen.getByLabelText(/accept cookies/i);
act(() => {
button.click();
});
expect(button).not.toBeInTheDocument();
expect(localStorage.setItem).toHaveBeenCalledWith(
USER_ACCEPTED_COOKIES_COOKIE_NAME,
USER_ACCEPTED_COOKIES_COOKIE_VALUE.ACCEPTED,
);
});
it('does not render the cookies banner when cookies are accepted', () => {
renderComponent();
const button = screen.getByLabelText(/accept cookies/i);
expect(button).toBeInTheDocument();
act(() => {
button.click();
});
renderComponent();
expect(localStorage.getItem).toHaveBeenCalledWith(USER_ACCEPTED_COOKIES_COOKIE_NAME);
expect(button).not.toBeInTheDocument();
});
});
import { selectCookieBanner } from '@/redux/cookieBanner/cookieBanner.selector';
import { acceptCookies, showBanner } from '@/redux/cookieBanner/cookieBanner.slice';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { Button } from '@/shared/Button';
import Link from 'next/link';
import { useEffect } from 'react';
import {
USER_ACCEPTED_COOKIES_COOKIE_NAME,
USER_ACCEPTED_COOKIES_COOKIE_VALUE,
} from './CookieBanner.constants';
export const CookieBanner = (): React.ReactNode => {
const dispatch = useAppDispatch();
const { visible, accepted } = useAppSelector(selectCookieBanner);
useEffect(() => {
const isAccepted =
localStorage.getItem(USER_ACCEPTED_COOKIES_COOKIE_NAME) ===
USER_ACCEPTED_COOKIES_COOKIE_VALUE.ACCEPTED;
if (isAccepted) {
dispatch(acceptCookies());
} else {
dispatch(showBanner());
}
}, [dispatch]);
const handleAcceptCookies = (): void => {
dispatch(acceptCookies());
localStorage.setItem(
USER_ACCEPTED_COOKIES_COOKIE_NAME,
USER_ACCEPTED_COOKIES_COOKIE_VALUE.ACCEPTED,
);
};
if (!visible || accepted) {
return null;
}
return (
<div className="absolute bottom-8 left-1/2 z-10 -translate-x-1/2 rounded-lg bg-white p-6 drop-shadow">
<h4 className="text-2xl font-bold">We use cookies!</h4>
<p className="my-4 leading-loose">
Minerva platform uses essential cookies to ensure its proper operation. For any queries in
relation to our policy on cookies and your choices, please{' '}
<Link href="/" className="font-semibold text-[#1C00DE]">
read here
</Link>
</p>
<Button
className="h-10 w-36 justify-center"
onClick={handleAcceptCookies}
aria-label="accept cookies"
>
Ok
</Button>
</div>
);
};
export const USER_ACCEPTED_COOKIES_COOKIE_NAME = 'cookiesAccepted';
export const USER_ACCEPTED_COOKIES_COOKIE_VALUE = {
ACCEPTED: 'true',
DECLINED: 'false',
};
export { CookieBanner } from './CookieBanner.component';
import { render, screen, fireEvent } from '@testing-library/react';
import { StoreType } from '@/redux/store';
import {
InitialStoreState,
getReduxWrapperWithStore,
} from '@/utils/testing/getReduxWrapperWithStore';
import { act } from 'react-dom/test-utils';
import { LoginModal } from './LoginModal.component';
const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => {
const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState);
return (
render(
<Wrapper>
<LoginModal />
</Wrapper>,
),
{
store,
}
);
};
test('renders LoginModal component', () => {
renderComponent();
const loginInput = screen.getByLabelText(/login/i);
const passwordInput = screen.getByLabelText(/password/i);
expect(loginInput).toBeInTheDocument();
expect(passwordInput).toBeInTheDocument();
});
test('handles input change correctly', () => {
renderComponent();
const loginInput: HTMLInputElement = screen.getByLabelText(/login/i);
const passwordInput: HTMLInputElement = screen.getByLabelText(/password/i);
fireEvent.change(loginInput, { target: { value: 'testuser' } });
fireEvent.change(passwordInput, { target: { value: 'testpassword' } });
expect(loginInput.value).toBe('testuser');
expect(passwordInput.value).toBe('testpassword');
});
test('submits form', () => {
renderComponent();
const loginInput = screen.getByLabelText(/login/i);
const passwordInput = screen.getByLabelText(/password/i);
const submitButton = screen.getByText(/submit/i);
fireEvent.change(loginInput, { target: { value: 'testuser' } });
fireEvent.change(passwordInput, { target: { value: 'testpassword' } });
act(() => {
submitButton.click();
});
expect(submitButton).toBeDisabled();
});
This diff is collapsed.
export { LoginModal } from './LoginModal.component';
import { OverviewImageLinkConfigSize } from './OverviewImageModal.types';
export const DEFAULT_OVERVIEW_IMAGE_LINK_CONFIG: OverviewImageLinkConfigSize = {
top: 0,
left: 0,
width: 0,
height: 0,
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment