1
1
package de .medizininformatikinitiative .torch .rest ;
2
2
3
3
import ca .uhn .fhir .context .FhirContext ;
4
+ import de .medizininformatikinitiative .torch .model .crtdl .ExtractDataParameters ;
4
5
import de .medizininformatikinitiative .torch .service .ExtractDataService ;
6
+ import de .medizininformatikinitiative .torch .util .CrtdlFactory ;
5
7
import de .medizininformatikinitiative .torch .util .ResultFileManager ;
6
8
import org .junit .jupiter .api .BeforeEach ;
7
9
import org .junit .jupiter .api .Nested ;
14
16
import org .springframework .http .HttpStatus ;
15
17
import org .springframework .http .MediaType ;
16
18
import org .springframework .test .web .reactive .server .WebTestClient ;
19
+ import reactor .core .publisher .Mono ;
17
20
18
21
import java .io .IOException ;
19
22
import java .util .Collections ;
20
23
import java .util .HashMap ;
21
24
import java .util .Map ;
22
25
23
26
import static org .assertj .core .api .Assertions .assertThat ;
27
+ import static org .mockito .ArgumentMatchers .any ;
24
28
import static org .mockito .ArgumentMatchers .anyString ;
25
29
import static org .mockito .ArgumentMatchers .eq ;
26
30
import static org .mockito .Mockito .when ;
27
31
28
32
@ ExtendWith (MockitoExtension .class )
29
33
class FhirControllerTest {
30
34
35
+ private final static String BASE_URL = "http://base-url" ;
36
+
31
37
@ Mock
32
38
ResultFileManager resultFileManager ;
33
39
@@ -42,25 +48,32 @@ class FhirControllerTest {
42
48
@ BeforeEach
43
49
void setup () {
44
50
FhirContext fhirContext = FhirContext .forR4 ();
45
- FhirController fhirController = new FhirController (
46
- fhirContext ,
47
- resultFileManager ,
48
- extractDataParametersParser ,
49
- extractDataService
50
- );
51
+ FhirController fhirController = new FhirController (fhirContext , resultFileManager , extractDataParametersParser , extractDataService , BASE_URL );
51
52
client = WebTestClient .bindToRouterFunction (fhirController .queryRouter ()).build ();
52
53
}
53
54
54
55
@ Test
55
56
void checkAcceptedStatus () {
56
57
when (resultFileManager .getStatus ("accepted-job" )).thenReturn (HttpStatus .ACCEPTED );
57
58
58
- var response = client .get ()
59
- .uri ("/fhir/__status/{jobId}" , "accepted-job" )
60
- .exchange ();
59
+ var response = client .get ().uri ("/fhir/__status/{jobId}" , "accepted-job" ).exchange ();
60
+
61
+ response .expectStatus ().isEqualTo (HttpStatus .ACCEPTED ).expectBody ().isEmpty ();
62
+ }
63
+
64
+ @ Test
65
+ void extractDataSuccess () {
66
+
67
+ ExtractDataParameters params = new ExtractDataParameters (CrtdlFactory .empty (), Collections .emptyList ());
68
+ when (extractDataParametersParser .parseParameters (any ())).thenReturn (params );
69
+ when (extractDataService .startJob (any (), any (), any ())).thenReturn (Mono .empty ());
70
+
71
+ WebTestClient .ResponseSpec response = client .post ().uri ("/fhir/$extract-data" ).contentType (MediaType .APPLICATION_JSON ).bodyValue ("{}" ).exchange ();
72
+
73
+ response .expectStatus ().isAccepted ().expectHeader ()
74
+ .value ("Content-Location" ,
75
+ location -> assertThat (location ).startsWith (BASE_URL + "/fhir/__status/" ));
61
76
62
- response .expectStatus ().isEqualTo (HttpStatus .ACCEPTED )
63
- .expectBody ().isEmpty ();
64
77
}
65
78
66
79
@ ParameterizedTest
@@ -77,52 +90,42 @@ void loadStatusBranches(String scenario, String expectedContentType, int expecte
77
90
78
91
case "ok" -> {
79
92
when (resultFileManager .getStatus (jobId )).thenReturn (HttpStatus .OK );
80
- when (resultFileManager .loadBundleFromFileSystem (eq (jobId ), anyString ()))
81
- .thenReturn (Map .of ("message" , "bundle content" ));
93
+ when (resultFileManager .loadBundleFromFileSystem (eq (jobId ), anyString ())).thenReturn (Map .of ("message" , "bundle content" ));
82
94
}
83
95
case "ok-null" -> {
84
96
when (resultFileManager .getStatus (jobId )).thenReturn (HttpStatus .OK );
85
- when (resultFileManager .loadBundleFromFileSystem (eq (jobId ), anyString ()))
86
- .thenReturn (Map .of ());
97
+ when (resultFileManager .loadBundleFromFileSystem (eq (jobId ), anyString ())).thenReturn (Map .of ());
87
98
}
88
99
case "missing" -> {
89
100
when (resultFileManager .getStatus (jobId )).thenReturn (HttpStatus .NOT_FOUND );
90
- when (resultFileManager .loadErrorFromFileSystem (jobId ))
91
- .thenReturn ("Error file not found for job: " + jobId );
101
+ when (resultFileManager .loadErrorFromFileSystem (jobId )).thenReturn ("Error file not found for job: " + jobId );
92
102
}
93
103
case "error" -> {
94
104
when (resultFileManager .getStatus (jobId )).thenReturn (HttpStatus .INTERNAL_SERVER_ERROR );
95
- when (resultFileManager .loadErrorFromFileSystem (jobId ))
96
- .thenReturn ("{\" resourceType\" :\" OperationOutcome\" }" );
105
+ when (resultFileManager .loadErrorFromFileSystem (jobId )).thenReturn ("{\" resourceType\" :\" OperationOutcome\" }" );
97
106
}
98
107
case "read-fail" -> {
99
108
when (resultFileManager .getStatus (jobId )).thenReturn (HttpStatus .INTERNAL_SERVER_ERROR );
100
109
// Throw the IOException when loadErrorFromFileSystem is called
101
- when (resultFileManager .loadErrorFromFileSystem (jobId ))
102
- .thenAnswer (invocation -> {
103
- throw new IOException ("disk failure" );
104
- });
110
+ when (resultFileManager .loadErrorFromFileSystem (jobId )).thenAnswer (invocation -> {
111
+ throw new IOException ("disk failure" );
112
+ });
105
113
}
106
114
default -> throw new IllegalArgumentException ("Unexpected scenario: " + scenario );
107
115
}
108
116
109
- var response = client .get ()
110
- .uri ("/fhir/__status/{jobId}" , jobId )
111
- .exchange ();
112
-
113
- response .expectStatus ().isEqualTo (expectedStatus )
114
- .expectHeader ().contentType (expectedContentType )
115
- .expectBody (String .class )
116
- .value (body -> {
117
- switch (scenario ) {
118
- case "ok" -> assertThat (body ).contains ("bundle content" );
119
- case "ok-null" -> assertThat (body ).contains ("Results could not be loaded for job: test-job" );
120
- case "error" -> assertThat (body ).contains ("\" resourceType\" :\" OperationOutcome\" " );
121
- case "missing" -> assertThat (body ).contains ("Error file not found for job" );
122
- case "read-fail" -> assertThat (body ).contains ("Error file could not be read: disk failure" );
123
- default -> throw new IllegalArgumentException ("Unexpected scenario: " + scenario );
124
- }
125
- });
117
+ var response = client .get ().uri ("/fhir/__status/{jobId}" , jobId ).exchange ();
118
+
119
+ response .expectStatus ().isEqualTo (expectedStatus ).expectHeader ().contentType (expectedContentType ).expectBody (String .class ).value (body -> {
120
+ switch (scenario ) {
121
+ case "ok" -> assertThat (body ).contains ("bundle content" );
122
+ case "ok-null" -> assertThat (body ).contains ("Results could not be loaded for job: test-job" );
123
+ case "error" -> assertThat (body ).contains ("\" resourceType\" :\" OperationOutcome\" " );
124
+ case "missing" -> assertThat (body ).contains ("Error file not found for job" );
125
+ case "read-fail" -> assertThat (body ).contains ("Error file could not be read: disk failure" );
126
+ default -> throw new IllegalArgumentException ("Unexpected scenario: " + scenario );
127
+ }
128
+ });
126
129
}
127
130
128
131
@@ -133,14 +136,10 @@ class StatusEndpointTests {
133
136
void emptyStatusMapReturnsEmptyJson () {
134
137
when (resultFileManager .getJobStatusMap ()).thenReturn (Collections .emptyMap ());
135
138
136
- var response = client .get ()
137
- .uri ("/fhir/__status/" );
139
+ var response = client .get ().uri ("/fhir/__status/" ).exchange ();
138
140
139
- response .exchange ()
140
- .expectStatus ().isOk ()
141
- .expectHeader ().contentType (MediaType .APPLICATION_JSON )
142
- .expectBody ()
143
- .json ("{}" );
141
+ response .expectStatus ().isOk ().expectHeader ().contentType (MediaType .APPLICATION_JSON )
142
+ .expectBody ().json ("{}" );
144
143
}
145
144
146
145
@ Test
@@ -150,11 +149,9 @@ void statusMapReturnsStatusText() {
150
149
map .put ("job2" , HttpStatus .OK );
151
150
when (resultFileManager .getJobStatusMap ()).thenReturn (map );
152
151
153
- var response = client .get ()
154
- .uri ("/fhir/__status/" );
152
+ var response = client .get ().uri ("/fhir/__status/" ).exchange ();
155
153
156
- response .exchange ().expectStatus ().isOk ()
157
- .expectHeader ().contentType (MediaType .APPLICATION_JSON )
154
+ response .expectStatus ().isOk ().expectHeader ().contentType (MediaType .APPLICATION_JSON )
158
155
.expectBody ()
159
156
.jsonPath ("$.job1" ).isEqualTo ("202 Accepted" )
160
157
.jsonPath ("$.job2" ).isEqualTo ("200 OK" );
@@ -166,27 +163,21 @@ class ExtractDataErrorBranchTests {
166
163
167
164
@ Test
168
165
void emptyRequestBodyTriggersBadRequest () {
169
- client .post ()
170
- .uri ("/fhir/$extract-data" )
171
- .exchange ()
172
- .expectStatus ().isBadRequest ()
166
+ var response = client .post ().uri ("/fhir/$extract-data" ).exchange ();
167
+
168
+ response .expectStatus ().isBadRequest ()
173
169
.expectHeader ().contentType ("application/fhir+json" )
174
170
.expectBody ()
175
171
.jsonPath ("$.resourceType" ).isEqualTo ("OperationOutcome" );
176
172
}
177
173
178
174
@ Test
179
175
void blankRequestBodyTriggersBadRequest () {
180
- client .post ()
181
- .uri ("/fhir/$extract-data" )
182
- .contentType (MediaType .APPLICATION_JSON )
183
- .bodyValue (" " )
184
- .exchange ()
185
- .expectStatus ().isBadRequest ()
186
- .expectHeader ().contentType ("application/fhir+json" )
176
+ var response = client .post ().uri ("/fhir/$extract-data" ).contentType (MediaType .APPLICATION_JSON ).bodyValue (" " ).exchange ();
177
+
178
+ response .expectStatus ().isBadRequest ().expectHeader ().contentType ("application/fhir+json" )
187
179
.expectBody ()
188
180
.jsonPath ("$.resourceType" ).isEqualTo ("OperationOutcome" );
189
-
190
181
}
191
182
}
192
183
}
0 commit comments