1 package de.dlr.shepard.common.search.query;
2
3 import static org.junit.jupiter.api.Assertions.assertEquals;
4 import static org.junit.jupiter.api.Assertions.assertThrows;
5
6 import de.dlr.shepard.common.exceptions.ShepardParserException;
7 import java.util.stream.Stream;
8 import org.junit.jupiter.api.Test;
9 import org.junit.jupiter.params.ParameterizedTest;
10 import org.junit.jupiter.params.provider.Arguments;
11 import org.junit.jupiter.params.provider.MethodSource;
12
13 public class MongoDBQueryBuilderTest {
14
15 private static Stream<Arguments> queryTest() {
16 var queryEq = Arguments.of(
17 """
18 {
19 "property": "name",
20 "value": "MyName",
21 "operator": "eq"
22 }
23 """,
24 "name: {$eq: \"MyName\"}"
25 );
26 var queryNe = Arguments.of(
27 """
28 {
29 "property": "name",
30 "value": "MyName",
31 "operator": "ne"
32 }
33 """,
34 "name: {$ne: \"MyName\"}"
35 );
36 var queryGt = Arguments.of(
37 """
38 {
39 "property": "name",
40 "value": "MyName",
41 "operator": "gt"
42 }
43 """,
44 "name: {$gt: \"MyName\"}"
45 );
46 var queryLt = Arguments.of(
47 """
48 {
49 "property": "name",
50 "value": "MyName",
51 "operator": "lt"
52 }
53 """,
54 "name: {$lt: \"MyName\"}"
55 );
56 var queryGe = Arguments.of(
57 """
58 {
59 "property": "name",
60 "value": "MyName",
61 "operator": "ge"
62 }
63 """,
64 "name: {$gte: \"MyName\"}"
65 );
66 var queryLe = Arguments.of(
67 """
68 {
69 "property": "name",
70 "value": "MyName",
71 "operator": "le"
72 }
73 """,
74 "name: {$lte: \"MyName\"}"
75 );
76 var queryIn = Arguments.of(
77 """
78 {
79 "property": "name",
80 "value": ["1","2"],
81 "operator": "in"
82 }
83 """,
84 "name: {$in: [\"1\",\"2\"]}"
85 );
86 var queryNot = Arguments.of(
87 """
88 {
89 "NOT":{
90 "property":"name",
91 "value":[
92 "1",
93 "2"
94 ],
95 "operator":"eq"
96 }
97 }
98 """,
99 "name: {$not: {$eq: [\"1\",\"2\"]}}"
100 );
101 var queryAnd = Arguments.of(
102 """
103 {
104 "AND":[
105 {
106 "property":"name",
107 "value":[
108 "1",
109 "2"
110 ],
111 "operator":"eq"
112 },
113 {
114 "property":"number",
115 "value":4,
116 "operator":"eq"
117 }
118 ]
119 }
120 """,
121 "$and: [{name: {$eq: [\"1\",\"2\"]}}, {number: {$eq: 4}}]"
122 );
123 var queryOr = Arguments.of(
124 """
125 {
126 "OR":[
127 {
128 "property":"name",
129 "value":[
130 "1",
131 "2"
132 ],
133 "operator":"eq"
134 },
135 {
136 "property":"number",
137 "value":4,
138 "operator":"eq"
139 }
140 ]
141 }
142 """,
143 "$or: [{name: {$eq: [\"1\",\"2\"]}}, {number: {$eq: 4}}]"
144 );
145 var queryNotNot = Arguments.of(
146 """
147 {
148 "NOT":{
149 "NOT":{
150 "property":"name",
151 "value":[
152 "1",
153 "2"
154 ],
155 "operator":"eq"
156 }
157 }
158 }
159 """,
160 "name: {$eq: [\"1\",\"2\"]}"
161 );
162 var queryNotOr = Arguments.of(
163 """
164 {
165 "NOT":{
166 "OR":[
167 {
168 "property":"name",
169 "value":[
170 "1",
171 "2"
172 ],
173 "operator":"eq"
174 },
175 {
176 "property":"number",
177 "value":4,
178 "operator":"eq"
179 }
180 ]
181 }
182 }
183 """,
184 "$and: [{name: {$not: {$eq: [\"1\",\"2\"]}}}, {number: {$not: {$eq: 4}}}]"
185 );
186 var queryNotAnd = Arguments.of(
187 """
188 {
189 "NOT":{
190 "AND":[
191 {
192 "property":"name",
193 "value":[
194 "1",
195 "2"
196 ],
197 "operator":"eq"
198 },
199 {
200 "property":"number",
201 "value":4,
202 "operator":"eq"
203 }
204 ]
205 }
206 }
207 """,
208 "$or: [{name: {$not: {$eq: [\"1\",\"2\"]}}}, {number: {$not: {$eq: 4}}}]"
209 );
210 return Stream.of(
211 queryEq,
212 queryNe,
213 queryGt,
214 queryLt,
215 queryGe,
216 queryLe,
217 queryIn,
218 queryNot,
219 queryAnd,
220 queryOr,
221 queryNotNot,
222 queryNotOr,
223 queryNotAnd
224 );
225 }
226
227 @ParameterizedTest
228 @MethodSource
229 public void queryTest(String input, String expected) {
230 String mongoDBQuery = MongoDBQueryBuilder.getMongoDBQueryString(input);
231 assertEquals(expected, mongoDBQuery);
232 }
233
234 @Test
235 public void queryTest_invalidJson() {
236 String input = "}";
237 assertThrows(ShepardParserException.class, () -> MongoDBQueryBuilder.getMongoDBQueryString(input));
238 }
239
240 @Test
241 public void queryTest_emptyJson() {
242 String input = "{}";
243 assertThrows(ShepardParserException.class, () -> MongoDBQueryBuilder.getMongoDBQueryString(input));
244 }
245
246 @Test
247 public void queryTest_invalidOperator() {
248 String input =
249 """
250 {
251 "property": "name",
252 "value": "1",
253 "operator": "invalid"
254 }
255 """;
256 assertThrows(ShepardParserException.class, () -> MongoDBQueryBuilder.getMongoDBQueryString(input));
257 }
258
259 @Test
260 public void queryTest_invalidBooleanOperator() {
261 String input =
262 """
263 {
264 "invalid": {
265 "property": "name",
266 "value": "1",
267 "operator": "eq"
268 }
269 }
270 """;
271 assertThrows(ShepardParserException.class, () -> MongoDBQueryBuilder.getMongoDBQueryString(input));
272 }
273
274 @Test
275 public void queryTest_invalidNegatedBooleanOperator() {
276 String input =
277 """
278 {
279 "NOT": {
280 "invalid": {
281 "property": "name",
282 "value": "1",
283 "operator": "eq"
284 }
285 }
286 }
287 """;
288 assertThrows(ShepardParserException.class, () -> MongoDBQueryBuilder.getMongoDBQueryString(input));
289 }
290 }