fhir-react 0.3.5 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/.circleci/config.yml +1 -1
  2. package/.eslintrc +10 -1
  3. package/.stylelintrc +6 -2
  4. package/README.md +19 -1
  5. package/build/index.js +15 -11
  6. package/build/style.css +9 -8
  7. package/package.json +55 -54
  8. package/src/assets/containers/AdverseEvent/adverse-event.svg +6 -0
  9. package/src/assets/containers/Coverage/coverage.svg +4 -0
  10. package/src/assets/containers/{ResourceCategory/resource-placeholder.svg → Generic/generic.svg} +0 -0
  11. package/src/assets/containers/MedicationDispense/medication-dispense.svg +5 -0
  12. package/src/assets/containers/MedicationOrder/medication-order.svg +5 -0
  13. package/src/assets/containers/MedicationRequest/medication-request.svg +5 -0
  14. package/src/assets/containers/Organization/organization.svg +5 -0
  15. package/src/assets/containers/PractitionerRole/practitioner-role.svg +5 -0
  16. package/src/assets/containers/ReferralRequest/referral-request.svg +8 -0
  17. package/src/assets/containers/RelatedPerson/related-person.svg +6 -0
  18. package/src/assets/containers/ResourceCategory/resource-category.svg +3 -0
  19. package/src/components/containers/Accordion/Accordion.js +21 -13
  20. package/src/components/datatypes/Attachment/Attachment.css +5 -0
  21. package/src/components/datatypes/Attachment/Attachment.js +7 -2
  22. package/src/components/datatypes/CodeableConcept/CodeableConcept.js +6 -3
  23. package/src/components/datatypes/Coding/Coding.js +7 -3
  24. package/src/components/datatypes/Identifier/Identifier.js +7 -3
  25. package/src/components/datatypes/Reference/Reference.js +7 -1
  26. package/src/components/datatypes/Telecom/Telecom.js +2 -3
  27. package/src/components/resources/AdverseEvent/AdverseEvent.js +81 -42
  28. package/src/components/resources/AdverseEvent/AdverseEvent.stories.js +12 -2
  29. package/src/components/resources/AdverseEvent/AdverseEvent.test.js +109 -2
  30. package/src/components/resources/AllergyIntolerance/AllergyIntolerance.js +9 -5
  31. package/src/components/resources/AllergyIntolerance/AllergyIntolerance.stories.js +5 -4
  32. package/src/components/resources/AllergyIntolerance/AllergyIntolerance.test.js +107 -1
  33. package/src/components/resources/Appointment/Appointment.js +2 -1
  34. package/src/components/resources/Appointment/Appointment.test.js +36 -1
  35. package/src/components/resources/Binary/Binary.js +1 -2
  36. package/src/components/resources/Binary/Binary.stories.js +10 -4
  37. package/src/components/resources/Binary/Binary.test.js +67 -0
  38. package/src/components/resources/Bundle/Bundle.css +7 -0
  39. package/src/components/resources/Bundle/Bundle.js +15 -11
  40. package/src/components/resources/Bundle/Bundle.stories.js +12 -78
  41. package/src/components/resources/Bundle/Bundle.test.js +0 -3
  42. package/src/components/resources/CarePlan/CarePlan.js +2 -1
  43. package/src/components/resources/CarePlan/CarePlan.stories.js +31 -5
  44. package/src/components/resources/CarePlan/CarePlan.test.js +114 -6
  45. package/src/components/resources/CareTeam/CareTeam.js +72 -50
  46. package/src/components/resources/CareTeam/CareTeam.stories.js +20 -3
  47. package/src/components/resources/CareTeam/CareTeam.test.js +109 -1
  48. package/src/components/resources/CareTeam/CareTeamParticipants.js +1 -1
  49. package/src/components/resources/Claim/CareTeam.js +55 -0
  50. package/src/components/resources/Claim/Claim.css +2 -11
  51. package/src/components/resources/Claim/Claim.js +158 -309
  52. package/src/components/resources/Claim/Claim.stories.js +37 -5
  53. package/src/components/resources/Claim/Claim.test.js +104 -1
  54. package/src/components/resources/Claim/Diagnosis.js +61 -0
  55. package/src/components/resources/Claim/Insurance.js +58 -0
  56. package/src/components/resources/Claim/Item.js +79 -0
  57. package/src/components/resources/Claim/Items.js +29 -0
  58. package/src/components/resources/ClaimResponse/AddedItem.js +61 -11
  59. package/src/components/resources/ClaimResponse/AddedItems.js +5 -9
  60. package/src/components/resources/ClaimResponse/ClaimResponse.js +137 -83
  61. package/src/components/resources/ClaimResponse/ClaimResponse.stories.js +15 -2
  62. package/src/components/resources/ClaimResponse/ClaimResponse.test.js +112 -1
  63. package/src/components/resources/ClaimResponse/Item.js +44 -9
  64. package/src/components/resources/ClaimResponse/Items.js +5 -4
  65. package/src/components/resources/Condition/Condition.js +3 -3
  66. package/src/components/resources/Condition/Condition.test.js +37 -4
  67. package/src/components/resources/Coverage/Coverage.js +97 -69
  68. package/src/components/resources/Coverage/Coverage.stories.js +31 -5
  69. package/src/components/resources/Coverage/Coverage.test.js +111 -4
  70. package/src/components/resources/Device/Device.js +2 -1
  71. package/src/components/resources/Device/Device.stories.js +33 -5
  72. package/src/components/resources/Device/Device.test.js +108 -1
  73. package/src/components/resources/DiagnosticReport/DiagnosticReport.js +7 -2
  74. package/src/components/resources/DiagnosticReport/DiagnosticReport.stories.js +5 -4
  75. package/src/components/resources/DiagnosticReport/DiagnosticReport.test.js +107 -1
  76. package/src/components/resources/DocumentReference/DocumentReference.js +7 -2
  77. package/src/components/resources/DocumentReference/DocumentReference.stories.js +3 -2
  78. package/src/components/resources/DocumentReference/DocumentReference.test.js +113 -1
  79. package/src/components/resources/Encounter/Encounter.js +2 -1
  80. package/src/components/resources/Encounter/Encounter.test.js +36 -1
  81. package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.js +2 -0
  82. package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.test.js +38 -1
  83. package/src/components/resources/FamilyMemberHistory/FamilyMemberHistory.js +7 -2
  84. package/src/components/resources/FamilyMemberHistory/FamilyMemberHistory.stories.js +3 -2
  85. package/src/components/resources/FamilyMemberHistory/FamilyMemberHistory.test.js +108 -1
  86. package/src/components/resources/Generic/Generic.js +20 -7
  87. package/src/components/resources/Generic/Generic.stories.js +2 -1
  88. package/src/components/resources/Generic/Generic.test.js +26 -7
  89. package/src/components/resources/Goal/Goal.js +3 -5
  90. package/src/components/resources/Goal/Goal.stories.js +5 -4
  91. package/src/components/resources/Goal/Goal.test.js +101 -1
  92. package/src/components/resources/Immunization/Immunization.js +2 -2
  93. package/src/components/resources/Immunization/Immunization.test.js +36 -1
  94. package/src/components/resources/List/DrugTierDefinitionExtension.js +79 -35
  95. package/src/components/resources/List/Entries.js +3 -3
  96. package/src/components/resources/List/List.js +135 -88
  97. package/src/components/resources/List/List.stories.js +38 -5
  98. package/src/components/resources/List/List.test.js +105 -1
  99. package/src/components/resources/Location/Location.js +65 -47
  100. package/src/components/resources/Location/Location.stories.js +11 -4
  101. package/src/components/resources/Location/Location.test.js +106 -4
  102. package/src/components/resources/Medication/Medication.js +91 -51
  103. package/src/components/resources/Medication/Medication.stories.js +37 -7
  104. package/src/components/resources/Medication/Medication.test.js +113 -4
  105. package/src/components/resources/MedicationAdministration/MedicationAdministration.js +86 -62
  106. package/src/components/resources/MedicationAdministration/MedicationAdministration.stories.js +7 -0
  107. package/src/components/resources/MedicationAdministration/MedicationAdministration.test.js +117 -1
  108. package/src/components/resources/MedicationDispense/DosageInstruction.js +25 -0
  109. package/src/components/resources/MedicationDispense/MedicationDispense.js +68 -68
  110. package/src/components/resources/MedicationDispense/MedicationDispense.stories.js +7 -0
  111. package/src/components/resources/MedicationDispense/MedicationDispense.test.js +108 -1
  112. package/src/components/resources/MedicationKnowledge/MedicationKnowledge.js +115 -66
  113. package/src/components/resources/MedicationKnowledge/MedicationKnowledge.stories.js +6 -0
  114. package/src/components/resources/MedicationKnowledge/MedicationKnowledge.test.js +110 -1
  115. package/src/components/resources/MedicationOrder/MedicationOrder.js +3 -4
  116. package/src/components/resources/MedicationOrder/MedicationOrder.stories.js +1 -2
  117. package/src/components/resources/MedicationOrder/MedicationOrder.test.js +102 -4
  118. package/src/components/resources/MedicationRequest/MedicationRequest.js +3 -4
  119. package/src/components/resources/MedicationRequest/MedicationRequest.stories.js +11 -6
  120. package/src/components/resources/MedicationRequest/MedicationRequest.test.js +100 -4
  121. package/src/components/resources/MedicationStatement/MedicationDosage.js +2 -2
  122. package/src/components/resources/MedicationStatement/MedicationStatement.js +8 -2
  123. package/src/components/resources/MedicationStatement/MedicationStatement.stories.js +5 -4
  124. package/src/components/resources/MedicationStatement/MedicationStatement.test.js +108 -1
  125. package/src/components/resources/Observation/Observation.js +2 -1
  126. package/src/components/resources/Observation/Observation.test.js +30 -1
  127. package/src/components/resources/Organization/Organization.js +56 -37
  128. package/src/components/resources/Organization/Organization.stories.js +15 -2
  129. package/src/components/resources/Organization/Organization.test.js +109 -1
  130. package/src/components/resources/Patient/Patient.js +2 -0
  131. package/src/components/resources/Patient/Patient.test.js +31 -2
  132. package/src/components/resources/Practitioner/Practitioner.js +2 -1
  133. package/src/components/resources/Practitioner/Practitioner.test.js +36 -1
  134. package/src/components/resources/PractitionerRole/PractitionerRole.js +50 -29
  135. package/src/components/resources/PractitionerRole/PractitionerRole.stories.js +7 -0
  136. package/src/components/resources/PractitionerRole/PractitionerRole.test.js +108 -1
  137. package/src/components/resources/Procedure/Procedure.js +2 -2
  138. package/src/components/resources/Procedure/Procedure.test.js +30 -1
  139. package/src/components/resources/Questionnaire/Group.js +53 -0
  140. package/src/components/resources/Questionnaire/Items.js +45 -0
  141. package/src/components/resources/Questionnaire/Questionnaire.css +24 -5
  142. package/src/components/resources/Questionnaire/Questionnaire.js +31 -170
  143. package/src/components/resources/Questionnaire/Questionnaire.stories.js +8 -0
  144. package/src/components/resources/Questionnaire/Questionnaire.test.js +194 -15
  145. package/src/components/resources/Questionnaire/Questions.js +40 -0
  146. package/src/components/resources/Questionnaire/getQuestionText.js +20 -0
  147. package/src/components/resources/QuestionnaireResponse/Answers.js +59 -0
  148. package/src/components/resources/QuestionnaireResponse/Group.js +70 -0
  149. package/src/components/resources/QuestionnaireResponse/Items.js +45 -0
  150. package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.css +33 -8
  151. package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.js +52 -236
  152. package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.stories.js +8 -0
  153. package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.test.js +38 -3
  154. package/src/components/resources/QuestionnaireResponse/Questions.js +43 -0
  155. package/src/components/resources/QuestionnaireResponse/getQuestionText.js +22 -0
  156. package/src/components/resources/ReferralRequest/ReferralRequest.js +65 -40
  157. package/src/components/resources/ReferralRequest/ReferralRequest.test.js +111 -11
  158. package/src/components/resources/RelatedPerson/RelatedPerson.js +151 -0
  159. package/src/components/resources/RelatedPerson/RelatedPerson.stories.js +46 -0
  160. package/src/components/resources/RelatedPerson/RelatedPerson.test.js +156 -0
  161. package/src/components/resources/RelatedPerson/index.js +3 -0
  162. package/src/components/resources/ResearchStudy/ResearchStudy.js +160 -130
  163. package/src/components/resources/ResearchStudy/ResearchStudy.stories.js +2 -0
  164. package/src/components/resources/ResearchStudy/ResearchStudy.test.js +108 -1
  165. package/src/components/resources/ResourceCategory/ResourceCategory.js +7 -12
  166. package/src/components/resources/ResourceCategory/ResourceCategory.stories.js +13 -2
  167. package/src/components/resources/ResourceCategory/ResourceCategory.test.js +77 -18
  168. package/src/components/ui/index.js +32 -12
  169. package/src/fixtures/dstu2/resources/relatedPerson/example1.json +79 -0
  170. package/src/fixtures/example-icons.jsx +81 -11
  171. package/src/fixtures/r4/resources/relatedPerson/example1.json +64 -0
  172. package/src/fixtures/stu3/resources/relatedPerson/example1.json +43 -0
  173. package/src/style.scss +3 -1
@@ -9,13 +9,15 @@ import UnhandledResourceDataStructure from '../UnhandledResourceDataStructure';
9
9
  import {
10
10
  Root,
11
11
  Body,
12
- Value,
13
12
  Table,
14
13
  TableRow,
15
14
  TableHeader,
16
15
  TableCell,
17
16
  MissingValue,
17
+ Header,
18
+ ValueSection,
18
19
  } from '../../ui';
20
+ import Accordion from '../../containers/Accordion';
19
21
 
20
22
  const commonDTO = fhirResource => {
21
23
  const typeCoding = _get(fhirResource, 'type.coding.0');
@@ -68,8 +70,7 @@ const resourceDTO = (fhirVersion, fhirResource) => {
68
70
  }
69
71
  };
70
72
 
71
- const ReferralRequest = props => {
72
- const { fhirResource, fhirVersion } = props;
73
+ const ReferralRequest = ({ fhirResource, fhirVersion, fhirIcons, onClick }) => {
73
74
  let fhirResourceData = {};
74
75
  try {
75
76
  fhirResourceData = resourceDTO(fhirVersion, fhirResource);
@@ -87,45 +88,69 @@ const ReferralRequest = props => {
87
88
  description,
88
89
  } = fhirResourceData;
89
90
 
91
+ const tableData = [
92
+ {
93
+ testId: 'dateSent',
94
+ data: <Date fhirData={dateSent} isBlack />,
95
+ status: dateSent,
96
+ },
97
+ {
98
+ testId: 'subject',
99
+ data: <span>{subject}</span>,
100
+ status: subject,
101
+ },
102
+ {
103
+ testId: 'requester',
104
+ data: <span>{requester}</span>,
105
+ status: requester,
106
+ },
107
+ {
108
+ testId: 'status',
109
+ data: <span>{status}</span>,
110
+ status: status,
111
+ },
112
+ ];
113
+
90
114
  return (
91
115
  <Root name="ReferralRequest">
92
- <Body>
93
- {typeCoding && (
94
- <Value label="Type" data-testid="typeCoding">
95
- <Coding fhirData={typeCoding} />
96
- </Value>
97
- )}
98
- <div className="overflow-auto">
99
- <Table>
100
- <thead>
101
- <TableRow>
102
- <TableHeader>Request sent</TableHeader>
103
- <TableHeader>Patient</TableHeader>
104
- <TableHeader>Requester</TableHeader>
105
- <TableHeader>status</TableHeader>
106
- </TableRow>
107
- </thead>
108
- <tbody>
109
- <TableRow>
110
- <TableCell data-testid="dateSent">
111
- {dateSent ? <Date fhirData={dateSent} /> : <MissingValue />}
112
- </TableCell>
113
- <TableCell data-testid="subject">
114
- {subject ? <span>{subject}</span> : <MissingValue />}
115
- </TableCell>
116
- <TableCell data-testid="requester">
117
- {requester ? <span>{requester}</span> : <MissingValue />}
118
- </TableCell>
119
- <TableCell data-testid="status">
120
- {status ? <span>{status}</span> : <MissingValue />}
121
- </TableCell>
122
- </TableRow>
123
- </tbody>
124
- </Table>
125
- </div>
126
- {reason && <div data-testid="reason">{reason}</div>}
127
- {description && <small data-testid="description">{description}</small>}
128
- </Body>
116
+ <Accordion
117
+ headerContent={
118
+ <Header
119
+ resourceName="ReferralRequest"
120
+ title={typeCoding && <Coding fhirData={typeCoding} />}
121
+ icon={fhirIcons}
122
+ />
123
+ }
124
+ bodyContent={
125
+ <Body>
126
+ <Table>
127
+ <thead>
128
+ <TableRow>
129
+ <TableHeader>Request sent</TableHeader>
130
+ <TableHeader>Patient</TableHeader>
131
+ <TableHeader>Requester</TableHeader>
132
+ <TableHeader>Status</TableHeader>
133
+ </TableRow>
134
+ </thead>
135
+ <tbody className="border-top-0">
136
+ <TableRow>
137
+ {tableData.map((element, index) => (
138
+ <TableCell key={index} data-testid={element.testId}>
139
+ {element.status ? element.data : <MissingValue />}
140
+ </TableCell>
141
+ ))}
142
+ </TableRow>
143
+ </tbody>
144
+ </Table>
145
+ {description && (
146
+ <ValueSection label={reason} data-testid="reason" marginTop>
147
+ <small className="text-secondary">{description}</small>
148
+ </ValueSection>
149
+ )}
150
+ </Body>
151
+ }
152
+ onClick={onClick}
153
+ />
129
154
  </Root>
130
155
  );
131
156
  };
@@ -1,12 +1,85 @@
1
1
  import React from 'react';
2
- import { render } from '@testing-library/react';
2
+ import { fireEvent, render } from '@testing-library/react';
3
3
 
4
4
  import ReferralRequest from './ReferralRequest';
5
5
  import fhirVersions from '../fhirResourceVersions';
6
6
  import dstu2Example1 from '../../../fixtures/dstu2/resources/referralRequest/example1.json';
7
7
  import stu3Example1 from '../../../fixtures/stu3/resources/referralRequest/example1.json';
8
8
 
9
+ import fhirIcons from '../../../fixtures/example-icons';
10
+
9
11
  describe('should render ReferralRequest component properly', () => {
12
+ it('component without a fhirIcons props should render a default icon', () => {
13
+ const defaultProps = {
14
+ fhirVersion: fhirVersions.DSTU2,
15
+ fhirResource: dstu2Example1,
16
+ };
17
+
18
+ const { getByAltText } = render(<ReferralRequest {...defaultProps} />);
19
+ const headerIcon = getByAltText('referral request');
20
+
21
+ expect(headerIcon.getAttribute('src')).toContain('IMAGE_MOCK');
22
+ });
23
+
24
+ it('component with a false as a fhirIcons props should render a placeholder', () => {
25
+ const defaultProps = {
26
+ fhirVersion: fhirVersions.DSTU2,
27
+ fhirResource: dstu2Example1,
28
+ fhirIcons: false,
29
+ };
30
+
31
+ const { getByTestId } = render(<ReferralRequest {...defaultProps} />);
32
+ const headerIcon = getByTestId('placeholder');
33
+
34
+ expect(headerIcon).toBeTruthy();
35
+ });
36
+
37
+ it('component with the img as a fhirIcons props should render an img', () => {
38
+ const defaultProps = {
39
+ fhirVersion: fhirVersions.DSTU2,
40
+ fhirResource: dstu2Example1,
41
+ fhirIcons: (
42
+ <img
43
+ src={require('../assets/containers/ReferralRequest/referral-request.svg')}
44
+ alt="referral request"
45
+ />
46
+ ),
47
+ };
48
+
49
+ const { getByAltText } = render(<ReferralRequest {...defaultProps} />);
50
+ const headerIcon = getByAltText('referral request');
51
+
52
+ expect(headerIcon.getAttribute('src')).toContain('IMAGE_MOCK');
53
+ });
54
+
55
+ it('component with the resources object as a fhirIcons props should render an img', () => {
56
+ const defaultProps = {
57
+ fhirVersion: fhirVersions.DSTU2,
58
+ fhirResource: dstu2Example1,
59
+ fhirIcons: fhirIcons,
60
+ };
61
+
62
+ const { getByAltText } = render(<ReferralRequest {...defaultProps} />);
63
+ const headerIcon = getByAltText('referral request');
64
+
65
+ expect(headerIcon.getAttribute('src')).toContain('IMAGE_MOCK');
66
+ });
67
+
68
+ it('component with the url as a fhirIcons props should render an img', () => {
69
+ const avatarSrc =
70
+ 'https://www.gravatar.com/avatar/?s=50&r=any&default=identicon&forcedefault=1';
71
+ const defaultProps = {
72
+ fhirVersion: fhirVersions.DSTU2,
73
+ fhirResource: dstu2Example1,
74
+ fhirIcons: avatarSrc,
75
+ };
76
+
77
+ const { getByAltText } = render(<ReferralRequest {...defaultProps} />);
78
+ const headerIcon = getByAltText('header icon');
79
+
80
+ expect(headerIcon.getAttribute('src')).toContain(avatarSrc);
81
+ });
82
+
10
83
  it('should render with DSTU2 source data', () => {
11
84
  const defaultProps = {
12
85
  fhirResource: dstu2Example1,
@@ -18,16 +91,11 @@ describe('should render ReferralRequest component properly', () => {
18
91
  );
19
92
  expect(container).not.toBeNull();
20
93
 
21
- expect(getByTestId('typeCoding').textContent).toContain(
22
- 'Referral for service',
23
- );
94
+ expect(getByTestId('title').textContent).toContain('Referral for service');
24
95
  expect(getByTestId('dateSent').textContent).toContain('2/14/2014');
25
96
  expect(getByTestId('reason').textContent).toContain(
26
97
  'For consideration of Grommets',
27
98
  );
28
- expect(getByTestId('description').textContent).toContain(
29
- 'In the past 2 years Beverly',
30
- );
31
99
  expect(getByTestId('subject').textContent).toContain('Beverly Weaver');
32
100
  expect(getByTestId('requester').textContent).toEqual('Serena Shrink');
33
101
  });
@@ -43,17 +111,49 @@ describe('should render ReferralRequest component properly', () => {
43
111
  );
44
112
  expect(container).not.toBeNull();
45
113
 
46
- expect(getByTestId('typeCoding').textContent).toContain(
114
+ expect(getByTestId('title').textContent).toContain(
47
115
  'Patient referral to specialist',
48
116
  );
49
117
  expect(getByTestId('dateSent').textContent).toContain('2/14/2014');
50
118
  expect(getByTestId('reason').textContent).toContain(
51
119
  'For consideration of Grommets',
52
120
  );
53
- expect(getByTestId('description').textContent).toContain(
54
- 'In the past 2 years Beverly',
55
- );
56
121
  expect(getByTestId('subject').textContent).toContain('Beverly Weaver');
57
122
  expect(getByTestId('requester').textContent).toEqual('Serena Shrink');
58
123
  });
124
+
125
+ it('should fire custom onClick function', () => {
126
+ const defaultProps = {
127
+ fhirResource: stu3Example1,
128
+ fhirVersion: fhirVersions.STU3,
129
+ };
130
+
131
+ const onClick = jest.fn();
132
+ const { getByRole } = render(
133
+ <ReferralRequest {...defaultProps} onClick={onClick} />,
134
+ );
135
+ const accordion = getByRole('button');
136
+ fireEvent.click(accordion);
137
+
138
+ const attribute = accordion.getAttribute('data-bs-toggle');
139
+ expect(attribute).not.toEqual('collapse');
140
+ expect(onClick).toHaveBeenCalled();
141
+ });
142
+
143
+ it('should not fire custom onClick function', () => {
144
+ const defaultProps = {
145
+ fhirResource: stu3Example1,
146
+ fhirVersion: fhirVersions.STU3,
147
+ };
148
+
149
+ const onClick = 'test';
150
+ const { getByRole } = render(
151
+ <ReferralRequest {...defaultProps} onClick={onClick} />,
152
+ );
153
+ const accordion = getByRole('button');
154
+ fireEvent.click(accordion);
155
+
156
+ const attribute = accordion.getAttribute('data-bs-toggle');
157
+ expect(attribute).toEqual('collapse');
158
+ });
59
159
  });
@@ -0,0 +1,151 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import _get from 'lodash/get';
4
+
5
+ import Telecom from '../../datatypes/Telecom';
6
+ import Address from '../../datatypes/Address';
7
+ import Accordion from '../../containers/Accordion';
8
+ import { Root, Header, MissingValue, Body } from '../../ui';
9
+ import UnhandledResourceDataStructure from '../UnhandledResourceDataStructure';
10
+ import Reference from '../../datatypes/Reference';
11
+ import fhirVersions from '../fhirResourceVersions';
12
+ import HumanName from '../../datatypes/HumanName';
13
+
14
+ const commonDTO = fhirResource => {
15
+ const patient = _get(fhirResource, 'patient');
16
+ const birthDate = _get(fhirResource, 'birthDate');
17
+ const gender = _get(fhirResource, 'gender');
18
+ const address = _get(fhirResource, 'address[0]');
19
+ const relatedPersonTelecom = _get(fhirResource, 'telecom', []).filter(
20
+ telecom => telecom.system === 'phone',
21
+ );
22
+
23
+ return {
24
+ patient,
25
+ birthDate,
26
+ gender,
27
+ address,
28
+ relatedPersonTelecom,
29
+ };
30
+ };
31
+
32
+ const dstu2DTO = fhirResource => {
33
+ const name = _get(fhirResource, 'name');
34
+
35
+ return {
36
+ name,
37
+ };
38
+ };
39
+
40
+ const stu3r4DTO = fhirResource => {
41
+ const name = _get(fhirResource, 'name')[0];
42
+
43
+ return {
44
+ name,
45
+ };
46
+ };
47
+
48
+ const resourceDTO = (fhirVersion, fhirResource) => {
49
+ switch (fhirVersion) {
50
+ case fhirVersions.DSTU2: {
51
+ return {
52
+ ...commonDTO(fhirResource),
53
+ ...dstu2DTO(fhirResource),
54
+ };
55
+ }
56
+
57
+ case fhirVersions.STU3:
58
+ case fhirVersions.R4: {
59
+ return {
60
+ ...commonDTO(fhirResource),
61
+ ...stu3r4DTO(fhirResource),
62
+ };
63
+ }
64
+
65
+ default:
66
+ throw Error('Unrecognized the fhir version property type.');
67
+ }
68
+ };
69
+
70
+ const RelatedPerson = ({ fhirResource, fhirVersion, fhirIcons, onClick }) => {
71
+ let fhirResourceData = {};
72
+ try {
73
+ fhirResourceData = resourceDTO(fhirVersion, fhirResource);
74
+ } catch (error) {
75
+ console.warn(error.message);
76
+ return <UnhandledResourceDataStructure resourceName="RelatedPerson" />;
77
+ }
78
+
79
+ const {
80
+ patient,
81
+ name,
82
+ birthDate,
83
+ gender,
84
+ address,
85
+ relatedPersonTelecom,
86
+ } = fhirResourceData;
87
+
88
+ const tableData = [
89
+ {
90
+ label: 'Patient',
91
+ testId: 'patient',
92
+ data: patient && <Reference fhirData={patient} />,
93
+ status: patient,
94
+ },
95
+ {
96
+ label: 'Address',
97
+ testId: 'address',
98
+ data: address && <Address fhirData={address} />,
99
+ status: address,
100
+ },
101
+ {
102
+ label: 'Telephone',
103
+ testId: 'telephone',
104
+ data: !relatedPersonTelecom ? (
105
+ <MissingValue />
106
+ ) : (
107
+ relatedPersonTelecom.map((telecom, index) => (
108
+ <Telecom key={index} fhirData={telecom} />
109
+ ))
110
+ ),
111
+ status: relatedPersonTelecom,
112
+ },
113
+ ];
114
+
115
+ return (
116
+ <Root name="RelatedPerson">
117
+ <Accordion
118
+ headerContent={
119
+ <Header
120
+ resourceName="RelatedPerson"
121
+ additionalContent={
122
+ (birthDate || gender) && (
123
+ <span className="text-gray-600">
124
+ {gender && (
125
+ <span data-testid="gender" className="text-capitalize">
126
+ {gender || 'unknown'}
127
+ </span>
128
+ )}
129
+ {gender && birthDate && ', '}
130
+ {birthDate && (
131
+ <span data-testid="birthDate">{birthDate}</span>
132
+ )}
133
+ </span>
134
+ )
135
+ }
136
+ icon={fhirIcons}
137
+ title={<HumanName fhirData={name} isTitle />}
138
+ />
139
+ }
140
+ bodyContent={<Body tableData={tableData} />}
141
+ onClick={onClick}
142
+ />
143
+ </Root>
144
+ );
145
+ };
146
+
147
+ RelatedPerson.propTypes = {
148
+ fhirResource: PropTypes.shape({}).isRequired,
149
+ };
150
+
151
+ export default RelatedPerson;
@@ -0,0 +1,46 @@
1
+ import React from 'react';
2
+ import { object } from '@storybook/addon-knobs';
3
+
4
+ import RelatedPerson from './RelatedPerson';
5
+ import fhirVersions from '../fhirResourceVersions';
6
+
7
+ import exampleDSTU2 from '../../../fixtures/dstu2/resources/relatedPerson/example1.json';
8
+ import exampleSTU3 from '../../../fixtures/stu3/resources/relatedPerson/example1.json';
9
+ import exampleR4 from '../../../fixtures/r4/resources/relatedPerson/example1.json';
10
+
11
+ import fhirIcons from '../../../fixtures/example-icons';
12
+
13
+ export default { title: 'RelatedPerson' };
14
+
15
+ export const ExampleDSTU2 = () => {
16
+ const fhirResource = object('Resource', exampleDSTU2);
17
+ return (
18
+ <RelatedPerson
19
+ fhirResource={fhirResource}
20
+ fhirVersion={fhirVersions.DSTU2}
21
+ fhirIcons={fhirIcons}
22
+ />
23
+ );
24
+ };
25
+
26
+ export const ExampleSTU3 = () => {
27
+ const fhirResource = object('Resource', exampleSTU3);
28
+ return (
29
+ <RelatedPerson
30
+ fhirResource={fhirResource}
31
+ fhirVersion={fhirVersions.STU3}
32
+ fhirIcons={false}
33
+ />
34
+ );
35
+ };
36
+
37
+ export const ExampleR4 = () => {
38
+ const fhirResource = object('Resource', exampleR4);
39
+ return (
40
+ <RelatedPerson
41
+ fhirResource={fhirResource}
42
+ fhirVersion={fhirVersions.R4}
43
+ fhirIcons={'random text'}
44
+ />
45
+ );
46
+ };
@@ -0,0 +1,156 @@
1
+ import React from 'react';
2
+ import { fireEvent, render } from '@testing-library/react';
3
+ import RelatedPerson from './RelatedPerson';
4
+ import fhirVersions from '../fhirResourceVersions';
5
+
6
+ import example1 from '../../../fixtures/dstu2/resources/relatedPerson/example1.json';
7
+ import example2 from '../../../fixtures/stu3/resources/relatedPerson/example1.json';
8
+ import example3 from '../../../fixtures/r4/resources/relatedPerson/example1.json';
9
+ import fhirIcons from '../../../fixtures/example-icons';
10
+
11
+ describe('should render component correctly', () => {
12
+ it('component without a fhirIcons props should render a default icon', () => {
13
+ const defaultProps = {
14
+ fhirResource: example1,
15
+ fhirVersion: fhirVersions.DSTU2,
16
+ };
17
+
18
+ const { getByAltText } = render(<RelatedPerson {...defaultProps} />);
19
+ const headerIcon = getByAltText('related person');
20
+
21
+ expect(headerIcon.getAttribute('src')).toContain('IMAGE_MOCK');
22
+ });
23
+
24
+ it('component with a false as a fhirIcons props should render a placeholder', () => {
25
+ const defaultProps = {
26
+ fhirResource: example1,
27
+ fhirVersion: fhirVersions.DSTU2,
28
+ fhirIcons: false,
29
+ };
30
+
31
+ const { getByTestId } = render(<RelatedPerson {...defaultProps} />);
32
+ const headerIcon = getByTestId('placeholder');
33
+
34
+ expect(headerIcon).toBeTruthy();
35
+ });
36
+
37
+ it('component with the img as a fhirIcons props should render an img', () => {
38
+ const defaultProps = {
39
+ fhirResource: example1,
40
+ fhirVersion: fhirVersions.DSTU2,
41
+ fhirIcons: (
42
+ <img
43
+ src={require('../assets/containers/RelatedPerson/related-person.svg')}
44
+ alt="related person"
45
+ />
46
+ ),
47
+ };
48
+
49
+ const { getByAltText } = render(<RelatedPerson {...defaultProps} />);
50
+ const headerIcon = getByAltText('related person');
51
+
52
+ expect(headerIcon.getAttribute('src')).toContain('IMAGE_MOCK');
53
+ });
54
+
55
+ it('component with the resources object as a fhirIcons props should render an img', () => {
56
+ const defaultProps = {
57
+ fhirResource: example1,
58
+ fhirVersion: fhirVersions.DSTU2,
59
+ fhirIcons: fhirIcons,
60
+ };
61
+
62
+ const { getByAltText } = render(<RelatedPerson {...defaultProps} />);
63
+ const headerIcon = getByAltText('related person');
64
+
65
+ expect(headerIcon.getAttribute('src')).toContain('IMAGE_MOCK');
66
+ });
67
+
68
+ it('component with the url as a fhirIcons props should render an img', () => {
69
+ const avatarSrc =
70
+ 'https://www.gravatar.com/avatar/?s=50&r=any&default=identicon&forcedefault=1';
71
+ const defaultProps = {
72
+ fhirResource: example1,
73
+ fhirVersion: fhirVersions.DSTU2,
74
+ fhirIcons: avatarSrc,
75
+ };
76
+
77
+ const { getByAltText } = render(<RelatedPerson {...defaultProps} />);
78
+ const headerIcon = getByAltText('header icon');
79
+
80
+ expect(headerIcon.getAttribute('src')).toContain(avatarSrc);
81
+ });
82
+
83
+ it('should render with DSTU2 source data', () => {
84
+ const defaultProps = {
85
+ fhirResource: example1,
86
+ fhirVersion: fhirVersions.DSTU2,
87
+ };
88
+ const { getByTestId } = render(<RelatedPerson {...defaultProps} />);
89
+
90
+ expect(getByTestId('gender').textContent).toEqual('female');
91
+ expect(getByTestId('address').textContent).toEqual(
92
+ '43, Place du Marché Sainte CatherineParis, 75004 FRA',
93
+ );
94
+ expect(getByTestId('telephone').textContent).toEqual('+33 (237) 998327');
95
+ });
96
+
97
+ it('should render with STU3 source data', () => {
98
+ const defaultProps = {
99
+ fhirResource: example2,
100
+ fhirVersion: fhirVersions.STU3,
101
+ };
102
+ const { getByTestId } = render(<RelatedPerson {...defaultProps} />);
103
+
104
+ expect(getByTestId('gender').textContent).toEqual('female');
105
+ expect(getByTestId('birthDate').textContent).toEqual('1963');
106
+ expect(getByTestId('telephone').textContent).toEqual('+31201234567');
107
+ });
108
+
109
+ it('should render with R4 source data', () => {
110
+ const defaultProps = {
111
+ fhirResource: example3,
112
+ fhirVersion: fhirVersions.R4,
113
+ };
114
+ const { getByTestId } = render(<RelatedPerson {...defaultProps} />);
115
+
116
+ expect(getByTestId('gender').textContent).toEqual('female');
117
+ expect(getByTestId('birthDate').textContent).toEqual('1973-05-31');
118
+ expect(getByTestId('address').textContent).toEqual('2222 Home Street ');
119
+ expect(getByTestId('telephone').textContent).toEqual('555-555-2003');
120
+ });
121
+
122
+ it('should fire custom onClick function', () => {
123
+ const defaultProps = {
124
+ fhirResource: example3,
125
+ fhirVersion: fhirVersions.R4,
126
+ };
127
+
128
+ const onClick = jest.fn();
129
+ const { getByRole } = render(
130
+ <RelatedPerson {...defaultProps} onClick={onClick} />,
131
+ );
132
+ const accordion = getByRole('button');
133
+ fireEvent.click(accordion);
134
+
135
+ const attribute = accordion.getAttribute('data-bs-toggle');
136
+ expect(attribute).not.toEqual('collapse');
137
+ expect(onClick).toHaveBeenCalled();
138
+ });
139
+
140
+ it('should not fire custom onClick function', () => {
141
+ const defaultProps = {
142
+ fhirResource: example3,
143
+ fhirVersion: fhirVersions.R4,
144
+ };
145
+
146
+ const onClick = 'test';
147
+ const { getByRole } = render(
148
+ <RelatedPerson {...defaultProps} onClick={onClick} />,
149
+ );
150
+ const accordion = getByRole('button');
151
+ fireEvent.click(accordion);
152
+
153
+ const attribute = accordion.getAttribute('data-bs-toggle');
154
+ expect(attribute).toEqual('collapse');
155
+ });
156
+ });
@@ -0,0 +1,3 @@
1
+ import RelatedPerson from './RelatedPerson';
2
+
3
+ export default RelatedPerson;