Skip to content

Commit

Permalink
UIU-3219 - navigate to pre patron registrations page and render list (#…
Browse files Browse the repository at this point in the history
…2755)

* UIU-3219 - navigate to pre patron registrations page  and  render list

* upgrade upload artifact version

* cleanup

* update unit test

* UIU-3219 - update tests

* UIU-3219 - update records count

* UIU-3219 - add interface dependency, fix review comments

* UIU-3219 - update query to fetch only 'TIER-2' records

* UIU-3219 - update test data for staging records with 'TIER-2' status

* UIU-3219 - update chanelog to reflect breaking change

* UIU-3221 - create new permission 'Users: Can view patron preregistration data'

* UIU-3219 - update tests for PatronPreRegistrationRecordsContainer

* UIU-3219 - update sub permission of permission 'Users: Can view patron preregistration data'

* UIU-3219 - fix rveiew comments

* UIU-3219 - fix lint issue
  • Loading branch information
Terala-Priyanka authored Oct 17, 2024
1 parent f106bde commit 7889b7d
Show file tree
Hide file tree
Showing 22 changed files with 836 additions and 7 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build-npm-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,15 @@ jobs:
data: ${{ steps.moduleDescriptor.outputs.content }}

- name: Upload event file
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Event File
path: ${{ github.event_path }}
retention-days: 30

- name: Upload Jest results
if: always()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: jest-test-results
path: ${{ env.JEST_JUNIT_OUTPUT_DIR }}/*.xml
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build-npm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,15 @@ jobs:
run: cat module-descriptor.json

- name: Upload event file
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Event File
path: ${{ github.event_path }}
retention-days: 30

- name: Upload Jest results
if: always()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: jest-test-results
path: ${{ env.JEST_JUNIT_OUTPUT_DIR }}/*.xml
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@
* Update `notes` to `v4.0`. Refs UIU-3229.
* Loan details: Print Due date receipt. Refs UIU-3210.
* Open loans: `isDcbItem()` must tolerate sparse data. Refs UIU-3230.
* *BREAKING* Add new okapi interface staging-users. Add action button for searching patrons pre registration records. Refs UIU-3219.
* Display patrons pre registration records results. Refs UIU-3222
* Create new permission 'Users: Can view patron preregistration data'. Refs UIU-3221.

## [10.1.2](https://github.com/folio-org/ui-users/tree/v10.1.2) (2024-09-05)
[Full Changelog](https://github.com/folio-org/ui-users/compare/v10.1.1...v10.1.2)
Expand Down
11 changes: 11 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"permissions": "5.6",
"login": "7.3",
"users-bl": "6.1",
"staging-users": "1.0",
"tags": "1.0"
},
"optionalOkapiInterfaces": {
Expand Down Expand Up @@ -1086,6 +1087,16 @@
"reading-room.patron-permission.item.put"
],
"visible": true
},
{
"permissionName": "ui-users.patron-pre-registrations-view",
"displayName": "Users: Can view patron preregistration data",
"subPermissions": [
"module.users.enabled",
"ui-users.view",
"staging-users.collection.get"
],
"visible": true
}
]
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useHistory } from 'react-router-dom';
import { FormattedMessage } from 'react-intl';

import { IfPermission } from '@folio/stripes/core';
import {
Button,
Icon,
} from '@folio/stripes/components';


const LinkToPatronPreRegistrations = () => {
const history = useHistory();

return (
<IfPermission perm="ui-users.patron-pre-registrations-view">
<Button
to={{
pathname: '/users/pre-registration-records',
state: {
pathname: history?.location?.pathname,
search: history?.location?.search,
},
}}
buttonStyle="dropdownItem"
>
<Icon icon="search">
<FormattedMessage id="ui-users.actionMenu.preRegistrationRecords" />
</Icon>
</Button>
</IfPermission>
);
};

export default LinkToPatronPreRegistrations;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {
screen,
render,
} from '@folio/jest-config-stripes/testing-library/react';
import { BrowserRouter as Router } from 'react-router-dom';
import { createMemoryHistory } from 'history';

import '../../../test/jest/__mock__';

import LinkToPatronPreRegistrations from './LinkToPatronPreRegistrations';

describe('LinkToPatronPreRegistrations', () => {
beforeEach(() => {
const history = createMemoryHistory();

render(
<Router history={history}>
<LinkToPatronPreRegistrations />
</Router>
);
});

it('should render button', () => {
expect(screen.getByText('ui-users.actionMenu.preRegistrationRecords')).toBeInTheDocument();
});
});
1 change: 1 addition & 0 deletions src/components/LinkToPatronPreRegistrations/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './LinkToPatronPreRegistrations';
2 changes: 2 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,5 @@ export const USER_INFO = {
export const USER_FIELDS_TO_CHECK = [USER_INFO.FIRST_NAME, USER_INFO.MIDDLE_NAME,
USER_INFO.MOBILE_PHONE, USER_INFO.PHONE, USER_INFO.PREFERRED_FIRST_NAME,
USER_INFO.BARCODE, USER_INFO.EXTERNAL_SYSTEM_ID, USER_INFO.USERNAME];

export const PATRON_PREREGISTRATION_RECORDS_NAME = 'patronPreRegistrationRecords';
8 changes: 8 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,14 @@ class UsersRouting extends React.Component {
<Route path={`${base}/:id/patronblocks/create`} component={Routes.PatronBlockContainer} />
<Route path={`${base}/create`} component={Routes.UserEditContainer} />
<Route path={`${base}/lost-items`} component={Routes.LostItemsContainer} />
<Route
path={`${base}/pre-registration-records`}
render={props => (
<IfPermission perm="ui-users.patron-pre-registrations-view">
<Routes.PatronPreRegistrationRecordsContainer {...props} />
</IfPermission>
)}
/>
<Route path={`${base}/patron-notice-print-jobs`} component={Routes.PatronNoticePrintJobsContainer} />
<Route path={`${base}/:id/edit`} component={Routes.UserEditContainer} />
<Route path={`${base}/view/:id`} component={Routes.UserDetailFullscreenContainer} />
Expand Down
96 changes: 96 additions & 0 deletions src/routes/PatronPreRegistrationRecordsContainer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom';
import { get } from 'lodash';

import { stripesConnect } from '@folio/stripes/core';
import {
makeQueryFunction,
StripesConnectedSource,
} from '@folio/stripes/smart-components';
import PatronsPreRegistrationListContainer from '../views/PatronsPreRegistrationListContainer/PatronsPreRegistrationListContainer';

import { PATRON_PREREGISTRATION_RECORDS_NAME } from '../constants';

const RESULT_COUNT_INCREMENT = 100;
const PAGE_AMOUNT = 100;

const PatronPreRegistrationRecordsContainer = ({
resources,
mutator,
stripes,
}) => {
const history = useHistory();
const source = new StripesConnectedSource({ resources, mutator }, stripes.logger, PATRON_PREREGISTRATION_RECORDS_NAME);
const data = get(resources, `${PATRON_PREREGISTRATION_RECORDS_NAME}.records`, []);

const queryGetter = () => {
return get(resources, 'query', {});
};

const onNeedMoreData = (askAmount, index) => {
const { resultOffset } = mutator;

if (source) {
if (resultOffset && index >= 0) {
source.fetchOffset(index);
} else {
source.fetchMore(RESULT_COUNT_INCREMENT);
}
}
};

const onClose = () => {
history.push('/users?sort=name');
};

return (
<PatronsPreRegistrationListContainer
onClose={onClose}
queryGetter={queryGetter}
onNeedMoreData={onNeedMoreData}
source={source}
data={data}
stripes={stripes}
/>
);
};

PatronPreRegistrationRecordsContainer.manifest = {
query: { initialValue: {} },
resultCount: { initialValue: 0 },
resultOffset: { initialValue: 0 },
[PATRON_PREREGISTRATION_RECORDS_NAME]: {
type: 'okapi',
records: 'staging_users',
resultOffset: '%{resultOffset}',
resultDensity: 'sparse',
perRequest: PAGE_AMOUNT,
path: 'staging-users',
GET: {
params: {
query: makeQueryFunction(
'cql.allRecords=1',
'(keywords="%{query.query}*") AND status == "TIER-2"',
{
'firstName': 'personal.firstName',
'lastName': 'personal.lastName',
'middleName': 'personal.middleName',
'preferredFirsName': 'personal.preferredFirstName',
'email': 'personal.email',
},
'',
2
),
},
staticFallback: { params: {} },
},
}
};

PatronPreRegistrationRecordsContainer.propTypes = {
mutator: PropTypes.object,
stripes: PropTypes.object,
resources: PropTypes.object,
};

export default stripesConnect(PatronPreRegistrationRecordsContainer);
118 changes: 118 additions & 0 deletions src/routes/PatronPreRegistrationRecordsContainer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { render, screen, fireEvent } from '@folio/jest-config-stripes/testing-library/react';

import preRegistrationRecords from 'fixtures/preRegistrationRecords';
import buildStripes from '__mock__/stripes.mock';

import { createMemoryHistory } from 'history';
import { MemoryRouter, useHistory } from 'react-router-dom';

import { StripesConnectedSource } from '@folio/stripes/smart-components';

import PatronPreRegistrationRecordsContainer from './PatronPreRegistrationRecordsContainer';

jest.unmock('@folio/stripes/components');
jest.unmock('@folio/stripes/smart-components');
jest.mock('@folio/stripes/components', () => ({
...jest.requireActual('@folio/stripes/components'),
SearchField: jest.fn((props) => (
<input
{...props}
/>
)),
}));
jest.mock('../views/PatronsPreRegistrationListContainer/PatronsPreRegistrationListContainer', () => {
return jest.fn(({ onClose, onNeedMoreData }) => (
<div data-testid="mock-PatronsPreRegistrationListContainer">
Mocked component PatronsPreRegistrationListContainer
<button data-testid="close-button" type="button" onClick={onClose}>close</button>
<button data-testid="need-more-button" type="button" onClick={() => onNeedMoreData(100, 1)}>Need more</button>
</div>
));
});
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useHistory: jest.fn(),
}));

const history = createMemoryHistory();
history.push = jest.fn();
const props = {
resources: {
patronPreRegistrationRecords: {
records: preRegistrationRecords,
},
resultCount: 1,
resultOffset: 0,
},
mutator: {
patronPreRegistrationRecords:{
GET: jest.fn(),
},
resultOffset: 100
},
stripes: buildStripes(),
history,
};

const renderPatronPreRegistrationRecordsContainer = (alteredProps) => render(
<MemoryRouter>
<PatronPreRegistrationRecordsContainer {...props} {...alteredProps} />
</MemoryRouter>
);

describe('PatronPreRegistrationRecordsContainer', () => {
let mockHistory;
let mockSource;

beforeEach(() => {
// Set up the mock history object
mockHistory = { push: jest.fn() };
useHistory.mockReturnValue(mockHistory);

// Mock the StripesConnectedSource instance
mockSource = {
fetchOffset: jest.fn(),
fetchMore: jest.fn(),
};

jest.spyOn(StripesConnectedSource.prototype, 'fetchOffset').mockImplementation(mockSource.fetchOffset);
jest.spyOn(StripesConnectedSource.prototype, 'fetchMore').mockImplementation(mockSource.fetchMore);
});

afterEach(() => {
jest.clearAllMocks();
});

it('should render', () => {
renderPatronPreRegistrationRecordsContainer();
expect(screen.getByTestId('mock-PatronsPreRegistrationListContainer')).toBeInTheDocument();
});

it('should call onClose method', () => {
renderPatronPreRegistrationRecordsContainer();
fireEvent.click(screen.getByTestId('close-button'));

expect(mockHistory.push).toHaveBeenCalledWith('/users?sort=name');
});

it('should call onNeedMoreData method', () => {
renderPatronPreRegistrationRecordsContainer();
fireEvent.click(screen.getByTestId('need-more-button'));

expect(mockSource.fetchOffset).toHaveBeenCalledWith(1);
});

it('should call onNeedMoreData method', () => {
const alteredProps = {
...props,
mutator: {
...props.mutator,
resultOffset: 0
},
};
renderPatronPreRegistrationRecordsContainer(alteredProps);
fireEvent.click(screen.getByTestId('need-more-button'));

expect(mockSource.fetchMore).toHaveBeenCalledWith(100);
});
});
1 change: 1 addition & 0 deletions src/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export { default as LoansListingContainer } from './LoansListingContainer';
export { default as LoanDetailContainer } from './LoanDetailContainer';
export { default as AccountDetailsContainer } from './AccountDetailsContainer';
export { default as LostItemsContainer } from './LostItemsContainer';
export { default as PatronPreRegistrationRecordsContainer } from './PatronPreRegistrationRecordsContainer';
export { default as PatronNoticePrintJobsContainer } from './PatronNoticePrintJobsContainer';
Loading

0 comments on commit 7889b7d

Please sign in to comment.