1+ /**
2+ * This Source Code Form is subject to the terms of the Mozilla Public License,
3+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4+ * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
5+ * the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
6+ *
7+ * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
8+ * graphic logo is a trademark of OpenMRS Inc.
9+ */
10+ package org .openmrs .module .webservices .rest .web .api .impl ;
11+
12+ import static org .hamcrest .CoreMatchers .hasItem ;
13+ import static org .hamcrest .CoreMatchers .is ;
14+ import static org .hamcrest .CoreMatchers .notNullValue ;
15+ import static org .hamcrest .CoreMatchers .nullValue ;
16+ import static org .hamcrest .MatcherAssert .assertThat ;
17+ import static org .hamcrest .Matchers .hasEntry ;
18+ import static org .hamcrest .Matchers .hasKey ;
19+ import static org .hamcrest .Matchers .hasSize ;
20+
21+ import java .util .Map ;
22+
23+ import org .junit .Before ;
24+ import org .junit .Test ;
25+ import org .openmrs .Patient ;
26+ import org .openmrs .Person ;
27+ import org .openmrs .module .webservices .rest .web .RequestContext ;
28+ import org .openmrs .module .webservices .rest .web .resource .api .Resource ;
29+ import org .openmrs .module .webservices .rest .web .resource .impl .DelegatingCrudResource ;
30+ import org .openmrs .module .webservices .rest .web .resource .impl .DelegatingResourceDescription ;
31+ import org .openmrs .module .webservices .rest .web .resource .impl .DelegatingSubResource ;
32+ import org .openmrs .module .webservices .rest .web .representation .Representation ;
33+ import org .openmrs .module .webservices .rest .web .response .ResourceDoesNotSupportOperationException ;
34+
35+ /**
36+ * Tests for {@link SchemaIntrospectionServiceImpl}.
37+ */
38+ public class SchemaIntrospectionServiceImplTest {
39+
40+ private SchemaIntrospectionServiceImpl service ;
41+
42+ @ Before
43+ public void setup () {
44+ service = new SchemaIntrospectionServiceImpl ();
45+ }
46+
47+ /**
48+ * @see SchemaIntrospectionServiceImpl#getDelegateType(Resource)
49+ */
50+ @ Test
51+ public void getDelegateType_shouldReturnNullForNullResource () {
52+ // Test with null resource
53+ assertThat (service .getDelegateType (null ), is (nullValue ()));
54+ }
55+
56+ /**
57+ * @see SchemaIntrospectionServiceImpl#getDelegateType(Resource)
58+ */
59+ @ Test
60+ public void getDelegateType_shouldReturnCorrectTypeForDelegatingCrudResource () {
61+ // Test with a mock DelegatingCrudResource
62+ TestPatientResource resource = new TestPatientResource ();
63+ Class <?> delegateType = service .getDelegateType (resource );
64+
65+ assertThat (delegateType , is (notNullValue ()));
66+ assertThat (delegateType .getName (), is (Patient .class .getName ()));
67+ }
68+
69+ /**
70+ * @see SchemaIntrospectionServiceImpl#getDelegateType(Resource)
71+ */
72+ @ Test
73+ public void getDelegateType_shouldReturnCorrectTypeForDelegatingSubResource () {
74+ // Test with a mock DelegatingSubResource
75+ TestPatientSubResource resource = new TestPatientSubResource ();
76+ Class <?> delegateType = service .getDelegateType (resource );
77+
78+ assertThat (delegateType , is (notNullValue ()));
79+ assertThat (delegateType .getName (), is (Patient .class .getName ()));
80+ }
81+
82+ /**
83+ * @see SchemaIntrospectionServiceImpl#discoverAvailableProperties(Class)
84+ */
85+ @ Test
86+ public void discoverAvailableProperties_shouldReturnEmptyMapForNullType () {
87+ Map <String , String > properties = service .discoverAvailableProperties (null );
88+
89+ assertThat (properties , is (notNullValue ()));
90+ assertThat (properties .size (), is (0 ));
91+ }
92+
93+ /**
94+ * @see SchemaIntrospectionServiceImpl#discoverAvailableProperties(Class)
95+ */
96+ @ Test
97+ public void discoverAvailableProperties_shouldIncludePropertiesFromGetters () {
98+ Map <String , String > properties = service .discoverAvailableProperties (Patient .class );
99+
100+ // Test a few essential properties that should be discovered via getters
101+ assertThat (properties , hasKey ("uuid" ));
102+ assertThat (properties , hasKey ("patientId" ));
103+ assertThat (properties , hasKey ("identifiers" ));
104+ assertThat (properties , hasKey ("person" ));
105+ assertThat (properties , hasKey ("voided" ));
106+ }
107+
108+ /**
109+ * @see SchemaIntrospectionServiceImpl#discoverAvailableProperties(Class)
110+ */
111+ @ Test
112+ public void discoverAvailableProperties_shouldIncludePropertiesFromSuperclasses () {
113+ Map <String , String > properties = service .discoverAvailableProperties (Patient .class );
114+
115+ // Patient extends Person, so should have Person properties
116+ assertThat (properties , hasKey ("gender" ));
117+ assertThat (properties , hasKey ("age" ));
118+ assertThat (properties , hasKey ("birthdate" ));
119+ assertThat (properties , hasKey ("names" ));
120+ assertThat (properties , hasKey ("addresses" ));
121+ }
122+
123+ /**
124+ * @see SchemaIntrospectionServiceImpl#discoverAvailableProperties(Class)
125+ */
126+ @ Test
127+ public void discoverAvailableProperties_shouldIncludePropertiesWithCorrectTypes () {
128+ Map <String , String > properties = service .discoverAvailableProperties (Patient .class );
129+
130+ // Verify some property types
131+ assertThat (properties , hasEntry ("uuid" , "String" ));
132+ assertThat (properties , hasEntry ("voided" , "Boolean" ));
133+ // Set of PatientIdentifier
134+ assertThat (properties .get ("identifiers" ).contains ("Set" ), is (true ));
135+ }
136+
137+ /**
138+ * @see SchemaIntrospectionServiceImpl#discoverResourceProperties(Resource)
139+ */
140+ @ Test
141+ public void discoverResourceProperties_shouldCombineGetDelegateTypeAndDiscoverAvailableProperties () {
142+ TestPatientResource resource = new TestPatientResource ();
143+ Map <String , String > properties = service .discoverResourceProperties (resource );
144+
145+ // Verify it discovered Patient properties
146+ assertThat (properties , hasKey ("uuid" ));
147+ assertThat (properties , hasKey ("patientId" ));
148+ assertThat (properties , hasKey ("identifiers" ));
149+
150+ // And Person properties (from superclass)
151+ assertThat (properties , hasKey ("gender" ));
152+ assertThat (properties , hasKey ("birthdate" ));
153+ }
154+
155+ /**
156+ * Mock DelegatingCrudResource for testing
157+ */
158+ private class TestPatientResource extends DelegatingCrudResource <Patient > {
159+
160+ @ Override
161+ public Patient newDelegate () {
162+ return new Patient ();
163+ }
164+
165+ @ Override
166+ public Patient save (Patient delegate ) {
167+ return delegate ;
168+ }
169+
170+ @ Override
171+ public Patient getByUniqueId (String uniqueId ) {
172+ return new Patient ();
173+ }
174+
175+ @ Override
176+ public void purge (Patient delegate , RequestContext context ) {
177+ }
178+
179+ @ Override
180+ public DelegatingResourceDescription getRepresentationDescription (Representation rep ) {
181+ return null ;
182+ }
183+
184+ @ Override
185+ public void delete (Patient delegate , String reason , RequestContext context ) throws ResourceDoesNotSupportOperationException {
186+ throw new ResourceDoesNotSupportOperationException ();
187+ }
188+ }
189+
190+ /**
191+ * Mock DelegatingSubResource for testing
192+ */
193+ private class TestPatientSubResource extends DelegatingSubResource <Patient , Person , TestPersonResource > {
194+
195+ @ Override
196+ public Patient getByUniqueId (String uniqueId ) {
197+ return new Patient ();
198+ }
199+
200+ @ Override
201+ public Patient newDelegate () {
202+ return new Patient ();
203+ }
204+
205+ @ Override
206+ public Patient save (Patient delegate ) {
207+ return delegate ;
208+ }
209+
210+ @ Override
211+ public void purge (Patient delegate , RequestContext context ) {
212+ }
213+
214+ @ Override
215+ public Person getParent (Patient instance ) {
216+ return instance .getPerson ();
217+ }
218+
219+ @ Override
220+ public void setParent (Patient instance , Person parent ) {
221+ // In actual Patient class, the setPerson method is generated by Hibernate
222+ // For our test, we'll just ignore the call
223+ }
224+
225+ @ Override
226+ public DelegatingResourceDescription getRepresentationDescription (Representation rep ) {
227+ return null ;
228+ }
229+
230+ @ Override
231+ public org .openmrs .module .webservices .rest .web .resource .api .PageableResult doGetAll (
232+ Person parent ,
233+ RequestContext context ) {
234+ return null ;
235+ }
236+
237+ @ Override
238+ public void delete (Patient delegate , String reason , RequestContext context ) throws ResourceDoesNotSupportOperationException {
239+ throw new ResourceDoesNotSupportOperationException ();
240+ }
241+ }
242+
243+ /**
244+ * Mock TestPersonResource for testing sub-resources
245+ */
246+ private class TestPersonResource extends DelegatingCrudResource <Person > {
247+
248+ @ Override
249+ public Person newDelegate () {
250+ return new Person ();
251+ }
252+
253+ @ Override
254+ public Person save (Person delegate ) {
255+ return delegate ;
256+ }
257+
258+ @ Override
259+ public Person getByUniqueId (String uniqueId ) {
260+ return new Person ();
261+ }
262+
263+ @ Override
264+ public void purge (Person delegate , RequestContext context ) {
265+ }
266+
267+ @ Override
268+ public DelegatingResourceDescription getRepresentationDescription (Representation rep ) {
269+ return null ;
270+ }
271+
272+ @ Override
273+ public void delete (Person delegate , String reason , RequestContext context ) throws ResourceDoesNotSupportOperationException {
274+ throw new ResourceDoesNotSupportOperationException ();
275+ }
276+ }
277+ }
0 commit comments