Skip to content

Commit

Permalink
self-checkout: make barcode always uppercase
Browse files Browse the repository at this point in the history
  • Loading branch information
ntarocco committed Oct 28, 2024
1 parent 48bb3aa commit b9ae86b
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 25 deletions.
18 changes: 11 additions & 7 deletions src/lib/pages/frontsite/SelfCheckout/ManualCheckout.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export class ManualCheckout extends React.Component {
super(props);

this.state = {
manualBarcode: null,
manualBarcode: '',
};
this.inputRef = React.createRef();
}
Expand All @@ -22,25 +22,29 @@ export class ManualCheckout extends React.Component {
}

render() {
const { show, onChange, label } = this.props;
const { show, onBarcodeInput, label } = this.props;
const { manualBarcode } = this.state;
if (show) {
return (
<Container className="pt-1 center">
<Message compact>
<Header className="pb-1" as="h5">
{label} Add the barcode manually:
{label} Insert the barcode manually:
</Header>
<Input
id="barcodeInput"
type="text"
placeholder="Barcode..."
className="pb-1"
ref={this.inputRef}
onChange={(e) => this.setState({ manualBarcode: e.target.value })}
value={manualBarcode}
onChange={(e) =>
this.setState({ manualBarcode: e.target.value?.toUpperCase() })
}
/>
<Button
onClick={() => onChange(manualBarcode)}
onClick={() => manualBarcode && onBarcodeInput(manualBarcode)}
disabled={!manualBarcode}
className="ml-10"
type="submit"
>
Expand All @@ -57,13 +61,13 @@ export class ManualCheckout extends React.Component {

ManualCheckout.propTypes = {
show: PropTypes.bool,
onChange: PropTypes.func.isRequired,
onBarcodeInput: PropTypes.func.isRequired,
label: PropTypes.string,
autofocus: PropTypes.bool,
};

ManualCheckout.defaultProps = {
show: false,
label: 'Cant scan the barcode?',
label: "Can't scan the barcode?",
autofocus: false,
};
9 changes: 5 additions & 4 deletions src/lib/pages/frontsite/SelfCheckout/SelfCheckout.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class SelfCheckout extends React.Component {

isItemLoanable = (itemBarcode) => {
const { user, item, notifyResultMessage } = this.props;
var resultMessage = `Book with barcode: ${itemBarcode} doesn't exist.`;
var resultMessage = `Book with barcode ${itemBarcode} not found.`;

if (!_isEmpty(item)) {
if (this.itemStatus(item).canCirculate()) {
Expand Down Expand Up @@ -147,11 +147,12 @@ class SelfCheckout extends React.Component {
<Header as="h1">SELF-CHECKOUT</Header>
<Container>
<BarcodeScanner onBarcodeDetected={this.onBarcodeDetected} />
<ManualCheckout show onChange={this.onBarcodeDetected} />
<ManualCheckout show onBarcodeInput={this.onBarcodeDetected} />
<Message warning compact>
If your browser isn't able to scan the barcode, try
Barcode not detected while scanning?
<br />
using another browser. (Recommended: Chrome)
Try using another browser. (Recommended:{' '}
<a href="https://www.google.com/chrome/">Google Chrome</a>)
</Message>
</Container>
<SelfCheckoutModal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export default class SelfCheckoutModal extends React.Component {
label="Wrong book?"
autofocus
show
onChange={onBarcodeDetected}
onBarcodeInput={onBarcodeDetected}
/>
</Modal.Content>
<Modal.Actions>
Expand Down
12 changes: 7 additions & 5 deletions src/lib/pages/frontsite/SelfCheckout/state/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ export const notifyResultMessage = (message) => {
};

const searchItem = async (dispatch, term) => {
const response = await itemApi.list(itemApi.query().withBarcode(term).qs());
const upperCasedTerm = term.toUpperCase();
const response = await itemApi.list(
itemApi.query().withBarcode(upperCasedTerm).qs()
);
const item = _first(response.data.hits) || null;

dispatch({
Expand Down Expand Up @@ -59,10 +62,9 @@ export const checkoutItem = (documentPid, itemPid, patronPid) => {
const { pid } = response.data.metadata;
const linkToLoan = (
<p>
The loan {pid} has been created by you!{' '}
<Link to={FrontSiteRoutes.patronProfile}>
You can now view the loan details.
</Link>
The loan {pid} has been created by you! You can view all your current
loans on your <Link to={FrontSiteRoutes.patronProfile}>profile</Link>{' '}
page.
</p>
);
dispatch(sendSuccessNotification('Success!', linkToLoan));
Expand Down
45 changes: 37 additions & 8 deletions src/lib/pages/frontsite/SelfCheckout/state/actions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,30 @@ import { itemApi } from '@api/items';
const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);

const mockList = jest.fn();
itemApi.list = mockList;
const itemApiListMock = jest.fn();
itemApi.list = itemApiListMock;

const response = { data: {} };
const expectedPayload = null;
const lowerCasedBarcode = 'cm-145123';
const upperCasedBarcode = lowerCasedBarcode.toUpperCase();

const expectedPayload = { pid: 'item-pid', barcode: upperCasedBarcode };
const response = {
data: {
hits: [expectedPayload],
},
};

let store;
beforeEach(() => {
mockList.mockClear();
itemApiListMock.mockClear();

store = mockStore(initialState);
store.clearActions();
});

describe('SelfCheck Out test', () => {
it('should dispatch an action updating the payloadresult item', async () => {
mockList.mockResolvedValue(response);
it('should dispatch an action updating the payload result item', async () => {
itemApiListMock.mockResolvedValue(response);

const expectedAction1 = {
type: actions.SEARCH_IS_LOADING,
Expand All @@ -32,7 +39,29 @@ describe('SelfCheck Out test', () => {
type: actions.SEARCH_ITEM_SUCCESS,
payload: expectedPayload,
};
await store.dispatch(actions.selfCheckOutSearch('123'));
await store.dispatch(actions.selfCheckOutSearch(lowerCasedBarcode));
expect(store.getActions()[0]).toEqual(expectedAction1);
expect(store.getActions()[1]).toEqual(expectedAction2);
expect(itemApiListMock).toHaveBeenCalledWith(
itemApi.query().withBarcode(upperCasedBarcode).qs()
);
});

it('should dispatch an error action when the search fails', async () => {
const errorMsg = 'Error message';
itemApiListMock.mockImplementation(() => {
throw new Error(errorMsg);
});

const expectedAction1 = {
type: actions.SEARCH_IS_LOADING,
};
const expectedAction2 = {
type: actions.SEARCH_HAS_ERROR,
payload: new Error(errorMsg),
};

await store.dispatch(actions.selfCheckOutSearch('syntax error query'));
expect(store.getActions()[0]).toEqual(expectedAction1);
expect(store.getActions()[1]).toEqual(expectedAction2);
});
Expand Down

0 comments on commit b9ae86b

Please sign in to comment.