forked from Expensify/App
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request Expensify#30068 from wlegolas/bugfix/issue-29614
Fix bug to show the secondary avatar when the repost is is a policy expense chat
- Loading branch information
Showing
3 changed files
with
244 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import Onyx from 'react-native-onyx'; | ||
import {cleanup, screen} from '@testing-library/react-native'; | ||
import * as LHNTestUtils from '../utils/LHNTestUtils'; | ||
import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; | ||
import wrapOnyxWithWaitForBatchedUpdates from '../utils/wrapOnyxWithWaitForBatchedUpdates'; | ||
|
||
const ONYXKEYS = { | ||
PERSONAL_DETAILS_LIST: 'personalDetailsList', | ||
IS_LOADING_REPORT_DATA: 'isLoadingReportData', | ||
COLLECTION: { | ||
REPORT_ACTIONS: 'reportActions_', | ||
POLICY: 'policy_', | ||
}, | ||
NETWORK: 'network', | ||
}; | ||
|
||
describe('ReportActionItemSingle', () => { | ||
beforeAll(() => | ||
Onyx.init({ | ||
keys: ONYXKEYS, | ||
registerStorageEventListener: () => {}, | ||
safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS], | ||
}), | ||
); | ||
|
||
beforeEach(() => { | ||
// Wrap Onyx each onyx action with waitForBatchedUpdates | ||
wrapOnyxWithWaitForBatchedUpdates(Onyx); | ||
// Initialize the network key for OfflineWithFeedback | ||
return Onyx.merge(ONYXKEYS.NETWORK, {isOffline: false}); | ||
}); | ||
|
||
// Clear out Onyx after each test so that each test starts with a clean slate | ||
afterEach(() => { | ||
cleanup(); | ||
Onyx.clear(); | ||
}); | ||
|
||
describe('when the Report is a policy expense chat', () => { | ||
describe('and the property "shouldShowSubscriptAvatar" is true', () => { | ||
const shouldShowSubscriptAvatar = true; | ||
const fakeReport = LHNTestUtils.getFakeReportWithPolicy([1, 2]); | ||
const fakeReportAction = LHNTestUtils.getFakeAdvancedReportAction(); | ||
const fakePolicy = LHNTestUtils.getFakePolicy(fakeReport.policyID); | ||
const fakePersonalDetails = { | ||
[fakeReportAction.actorAccountID]: { | ||
accountID: fakeReportAction.actorAccountID, | ||
login: '[email protected]', | ||
displayName: 'Email One', | ||
avatar: 'https://example.com/avatar.png', | ||
firstName: 'One', | ||
}, | ||
}; | ||
|
||
beforeEach(() => { | ||
LHNTestUtils.getDefaultRenderedReportActionItemSingle(shouldShowSubscriptAvatar, fakeReport, fakeReportAction); | ||
}); | ||
|
||
function setup() { | ||
return waitForBatchedUpdates().then(() => | ||
Onyx.multiSet({ | ||
[ONYXKEYS.PERSONAL_DETAILS_LIST]: fakePersonalDetails, | ||
[ONYXKEYS.IS_LOADING_REPORT_DATA]: false, | ||
[`${ONYXKEYS.COLLECTION.POLICY}${fakeReport.policyID}`]: fakePolicy, | ||
}), | ||
); | ||
} | ||
|
||
it('renders secondary Avatar properly', () => { | ||
const expectedSecondaryIconTestId = 'SvgDefaultAvatar_w Icon'; | ||
|
||
return setup().then(() => { | ||
expect(screen.getByTestId(expectedSecondaryIconTestId)).toBeDefined(); | ||
}); | ||
}); | ||
|
||
it('renders Person information', () => { | ||
const [expectedPerson] = fakeReportAction.person; | ||
|
||
return setup().then(() => { | ||
expect(screen.getByText(expectedPerson.text)).toBeDefined(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,10 +5,13 @@ import ComposeProviders from '../../src/components/ComposeProviders'; | |
import OnyxProvider from '../../src/components/OnyxProvider'; | ||
import {LocaleContextProvider} from '../../src/components/LocaleContextProvider'; | ||
import SidebarLinksData from '../../src/pages/home/sidebar/SidebarLinksData'; | ||
import ReportActionItemSingle from '../../src/pages/home/report/ReportActionItemSingle'; | ||
import {EnvironmentProvider} from '../../src/components/withEnvironment'; | ||
import {CurrentReportIDContextProvider} from '../../src/components/withCurrentReportID'; | ||
import CONST from '../../src/CONST'; | ||
import DateUtils from '../../src/libs/DateUtils'; | ||
import reportPropTypes from '../../src/pages/reportPropTypes'; | ||
import reportActionPropTypes from '../../src/pages/home/report/reportActionPropTypes'; | ||
|
||
// we have to mock `useIsFocused` because it's used in the SidebarLinks component | ||
const mockedNavigate = jest.fn(); | ||
|
@@ -167,6 +170,63 @@ function getAdvancedFakeReport(isArchived, isUserCreatedPolicyRoom, hasAddWorksp | |
}; | ||
} | ||
|
||
/** | ||
* @param {Number[]} [participantAccountIDs] | ||
* @param {Number} [millisecondsInThePast] the number of milliseconds in the past for the last message timestamp (to order reports by most recent messages) | ||
* @param {boolean} [isUnread] | ||
* @returns {Object} | ||
*/ | ||
function getFakeReportWithPolicy(participantAccountIDs = [1, 2], millisecondsInThePast = 0, isUnread = false) { | ||
return { | ||
...getFakeReport(participantAccountIDs, millisecondsInThePast, isUnread), | ||
type: CONST.REPORT.TYPE.CHAT, | ||
chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT, | ||
policyID: '08CE60F05A5D86E1', | ||
oldPolicyName: '', | ||
isOwnPolicyExpenseChat: false, | ||
ownerAccountID: participantAccountIDs[0], | ||
}; | ||
} | ||
|
||
/** | ||
* @param {Number} [id] | ||
* @param {String} [name] | ||
* @returns {Object} | ||
*/ | ||
function getFakePolicy(id = 1, name = 'Workspace-Test-001') { | ||
return { | ||
id, | ||
name, | ||
isFromFullPolicy: false, | ||
role: 'admin', | ||
type: 'free', | ||
owner: '[email protected]', | ||
outputCurrency: 'BRL', | ||
avatar: '', | ||
employeeList: [], | ||
isPolicyExpenseChatEnabled: true, | ||
areChatRoomsEnabled: true, | ||
lastModified: 1697323926777105, | ||
autoReporting: true, | ||
autoReportingFrequency: 'immediate', | ||
defaultBillable: false, | ||
disabledFields: {defaultBillable: true, reimbursable: false}, | ||
}; | ||
} | ||
|
||
/** | ||
* @param {String} actionName | ||
* @param {String} actor | ||
* @param {Number} millisecondsInThePast the number of milliseconds in the past for the last message timestamp (to order reports by most recent messages) | ||
* @returns {Object} | ||
*/ | ||
function getFakeAdvancedReportAction(actionName = 'IOU', actor = '[email protected]', millisecondsInThePast = 0) { | ||
return { | ||
...getFakeReportAction(actor, millisecondsInThePast), | ||
actionName, | ||
}; | ||
} | ||
|
||
/** | ||
* @param {String} [currentReportID] | ||
*/ | ||
|
@@ -218,4 +278,97 @@ MockedSidebarLinks.defaultProps = { | |
currentReportID: '', | ||
}; | ||
|
||
export {fakePersonalDetails, getDefaultRenderedSidebarLinks, getAdvancedFakeReport, getFakeReport, getFakeReportAction, MockedSidebarLinks}; | ||
/** | ||
* @param {React.ReactElement} component | ||
*/ | ||
function internalRender(component) { | ||
// A try-catch block needs to be added to the rendering so that any errors that happen while the component | ||
// renders are caught and logged to the console. Without the try-catch block, Jest might only report the error | ||
// as "The above error occurred in your component", without providing specific details. By using a try-catch block, | ||
// any errors are caught and logged, allowing you to identify the exact error that might be causing a rendering issue | ||
// when developing tests. | ||
|
||
try { | ||
render(component); | ||
} catch (error) { | ||
console.error(error); | ||
} | ||
} | ||
|
||
/** | ||
* @param {Boolean} [shouldShowSubscriptAvatar] | ||
* @param {Object} [report] | ||
* @param {Object} [reportAction] | ||
*/ | ||
function getDefaultRenderedReportActionItemSingle(shouldShowSubscriptAvatar = true, report = null, reportAction = null) { | ||
const currentReport = report || getFakeReport(); | ||
const currentReportAction = reportAction || getFakeAdvancedReportAction(); | ||
|
||
internalRender( | ||
<MockedReportActionItemSingle | ||
shouldShowSubscriptAvatar={shouldShowSubscriptAvatar} | ||
report={currentReport} | ||
reportAction={currentReportAction} | ||
/>, | ||
); | ||
} | ||
|
||
/** | ||
* @param {Boolean} shouldShowSubscriptAvatar | ||
* @param {Object} report | ||
* @param {Object} reportAction | ||
* @returns {JSX.Element} | ||
*/ | ||
function MockedReportActionItemSingle({shouldShowSubscriptAvatar, report, reportAction}) { | ||
const personalDetailsList = { | ||
[reportAction.actorAccountID]: { | ||
accountID: reportAction.actorAccountID, | ||
login: '[email protected]', | ||
displayName: 'Email One', | ||
avatar: 'https://example.com/avatar.png', | ||
firstName: 'One', | ||
}, | ||
}; | ||
|
||
return ( | ||
<ComposeProviders components={[OnyxProvider, LocaleContextProvider, EnvironmentProvider, CurrentReportIDContextProvider]}> | ||
<ReportActionItemSingle | ||
action={reportAction} | ||
report={report} | ||
personalDetailsList={personalDetailsList} | ||
wrapperStyles={[{display: 'inline'}]} | ||
showHeader | ||
shouldShowSubscriptAvatar={shouldShowSubscriptAvatar} | ||
hasBeenFlagged={false} | ||
iouReport={undefined} | ||
isHovered={false} | ||
/> | ||
</ComposeProviders> | ||
); | ||
} | ||
|
||
MockedReportActionItemSingle.propTypes = { | ||
shouldShowSubscriptAvatar: PropTypes.bool, | ||
report: reportPropTypes, | ||
reportAction: PropTypes.shape(reportActionPropTypes), | ||
}; | ||
|
||
MockedReportActionItemSingle.defaultProps = { | ||
shouldShowSubscriptAvatar: true, | ||
report: null, | ||
reportAction: null, | ||
}; | ||
|
||
export { | ||
fakePersonalDetails, | ||
getDefaultRenderedSidebarLinks, | ||
getAdvancedFakeReport, | ||
getFakeReport, | ||
getFakeReportAction, | ||
MockedSidebarLinks, | ||
getDefaultRenderedReportActionItemSingle, | ||
MockedReportActionItemSingle, | ||
getFakeReportWithPolicy, | ||
getFakePolicy, | ||
getFakeAdvancedReportAction, | ||
}; |