1+
2+ import com.mongodb.client.model.*
3+ import com.mongodb.kotlin.client.coroutine.MongoClient
4+ import io.github.cdimascio.dotenv.dotenv
5+ import kotlinx.coroutines.delay
6+ import kotlinx.coroutines.flow.count
7+ import kotlinx.coroutines.flow.firstOrNull
8+ import kotlinx.coroutines.flow.toList
9+ import kotlinx.coroutines.launch
10+ import kotlinx.coroutines.runBlocking
11+ import org.junit.jupiter.api.AfterAll
12+ import org.junit.jupiter.api.AfterEach
13+ import org.junit.jupiter.api.BeforeEach
14+ import org.junit.jupiter.api.Test
15+ import kotlin.test.assertEquals
16+ import kotlin.test.assertIs
17+
18+ class QuickReferenceTest {
19+
20+ // :snippet-start: data-model
21+ data class Movie (
22+ val title : String ,
23+ val year : Int ,
24+ val rated : String? = " Not Rated" ,
25+ val genres : List <String >? = listOf()
26+ )
27+ // :snippet-end:
28+
29+ companion object {
30+ val dotenv = dotenv()
31+ val client = MongoClient .create(dotenv[" MONGODB_CONNECTION_URI" ])
32+ val database = client.getDatabase(" sample_mflix" )
33+ val collection = database.getCollection<Movie >(" movies" )
34+
35+ @AfterAll
36+ @JvmStatic
37+ fun afterAll () {
38+ client.close()
39+ }
40+ }
41+
42+ @BeforeEach
43+ fun beforeEach () {
44+ runBlocking {
45+ collection.insertMany(
46+ listOf (
47+ Movie (" Shrek" , 2001 ),
48+ Movie (" Shrek 2" , 2004 ),
49+ Movie (" Shrek the Third" , 2007 ),
50+ Movie (" Shrek Forever After" , 2010 ),
51+ )
52+ )
53+ }
54+ }
55+
56+ @AfterEach
57+ fun afterEach () {
58+ runBlocking {
59+ collection.dropIndexes()
60+ collection.drop()
61+ }
62+ }
63+
64+ @Test
65+ fun findDocumentTestTest () = runBlocking {
66+ val shrek =
67+ // :snippet-start: find-document
68+ collection.find(
69+ Filters .eq(Movie ::title.name, " Shrek" )
70+ ).firstOrNull()
71+ // :snippet-end:
72+ println (shrek)
73+ assertEquals(" Shrek" , shrek?.title)
74+ }
75+
76+ @Test
77+ fun findMultipleDocumentsTestTest () = runBlocking {
78+ val movies =
79+ // :snippet-start: find-multiple-documents
80+ collection.find(
81+ Filters .eq(Movie ::year.name, 2004 )
82+ )
83+ // :snippet-end:
84+ println (movies.toList())
85+ assertEquals(1 , movies.count())
86+ }
87+
88+ @Test
89+ fun insertDocumentTest () = runBlocking {
90+ collection.deleteOne(Filters .eq(Movie ::title.name, " Shrek" ))
91+ val insertResult =
92+ // :snippet-start: insert-document
93+ collection.insertOne(Movie (" Shrek" , 2001 ))
94+ // :snippet-end:
95+ assert (insertResult.wasAcknowledged())
96+ assertEquals(4 , collection.countDocuments())
97+ }
98+
99+ @Test
100+ fun insertMultipleDocumentsTest () = runBlocking {
101+ collection.drop()
102+ val insertResult =
103+ // :snippet-start: insert-multiple-documents
104+ collection.insertMany(
105+ listOf (
106+ Movie (" Shrek" , 2001 ),
107+ Movie (" Shrek 2" , 2004 ),
108+ Movie (" Shrek the Third" , 2007 ),
109+ Movie (" Shrek Forever After" , 2010 ),
110+ )
111+ )
112+ // :snippet-end:
113+ assert (insertResult.wasAcknowledged())
114+ assertEquals(4 , collection.countDocuments())
115+ }
116+
117+ @Test
118+ fun updateDocumentTest () = runBlocking {
119+ val updateResult =
120+ // :snippet-start: update-document
121+ collection.updateOne(
122+ Filters .eq(Movie ::title.name, " Shrek" ),
123+ Updates .set(Movie ::rated.name, " PG" )
124+ )
125+ // :snippet-end:
126+ val updatedShrek = collection.find(Filters .eq(Movie ::title.name, " Shrek" )).firstOrNull()
127+ println (updatedShrek)
128+ assert (updateResult.wasAcknowledged())
129+ assertEquals(" PG" , updatedShrek?.rated)
130+ }
131+
132+ @Test
133+ fun updateMultipleDocumentsTest () = runBlocking {
134+ val updateMultipleResult =
135+ // :snippet-start: update-multiple-documents
136+ collection.updateMany(
137+ Filters .regex(Movie ::title.name, " Shrek" ),
138+ Updates .set(Movie ::rated.name, " PG" )
139+ )
140+ // :snippet-end:
141+ val pgMovies = collection.find(Filters .eq(Movie ::rated.name, " PG" )).toList()
142+ println (pgMovies)
143+ assert (updateMultipleResult.wasAcknowledged())
144+ assertEquals(4 , pgMovies.size)
145+ }
146+
147+ @Test
148+ fun updateArrayInDocumentTest () = runBlocking {
149+ val updateMultipleResult =
150+ // :snippet-start: update-array-in-document
151+ collection.updateOne(
152+ Filters .eq(Movie ::title.name, " Shrek" ),
153+ Updates .addEachToSet(Movie ::genres.name, listOf (" Family" , " Fantasy" ))
154+ )
155+ // :snippet-end:
156+ val updatedShrek = collection.find(Filters .eq(Movie ::title.name, " Shrek" )).firstOrNull()
157+ println (updatedShrek)
158+ assert (updateMultipleResult.wasAcknowledged())
159+ assertEquals(listOf (" Family" , " Fantasy" ), updatedShrek?.genres)
160+ }
161+
162+ @Test
163+ fun replaceDocumentTest () = runBlocking {
164+ val replaceResult =
165+ // :snippet-start: replace-document
166+ collection.replaceOne(
167+ Filters .eq(Movie ::title.name, " Shrek" ),
168+ Movie (" Kersh" , 1002 , " GP" )
169+ )
170+ // :snippet-end:
171+ val kersh = collection.find(Filters .eq(Movie ::title.name, " Kersh" )).firstOrNull()
172+ println (kersh)
173+ assert (replaceResult.wasAcknowledged())
174+ assertEquals(" GP" , kersh?.rated)
175+ }
176+
177+ @Test
178+ fun deleteDocumentTest () = runBlocking {
179+ val deleteResult =
180+ // :snippet-start: delete-document
181+ collection.deleteOne(
182+ Filters .eq(Movie ::title.name, " Shrek" )
183+ )
184+ // :snippet-end:
185+ assert (deleteResult.wasAcknowledged())
186+ assertEquals(3 , collection.countDocuments())
187+ }
188+
189+ @Test
190+ fun deleteMultipleDocumentsTest () = runBlocking {
191+ val deleteResult =
192+ // :snippet-start: delete-multiple-documents
193+ collection.deleteMany(
194+ Filters .regex(Movie ::title.name, " Shrek" )
195+ )
196+ // :snippet-end:
197+ assert (deleteResult.wasAcknowledged())
198+ assertEquals(0 , collection.countDocuments())
199+ }
200+
201+ @Test
202+ fun bulkWriteTest () = runBlocking {
203+ collection.deleteOne(Filters .eq(Movie ::title.name, " Shrek" ))
204+ val bulkWriteResult =
205+ // :snippet-start: bulk-write
206+ collection.bulkWrite(
207+ listOf (
208+ InsertOneModel (Movie (" Shrek" , 2001 )),
209+ DeleteManyModel (Filters .lt(Movie ::year.name, 2004 )),
210+ )
211+ )
212+ // :snippet-end:
213+ assert (bulkWriteResult.wasAcknowledged())
214+ assertEquals(3 , collection.countDocuments())
215+
216+ }
217+
218+ @Test
219+ fun watchForChangesTest () = runBlocking {
220+ var callCount = 0
221+ val job = launch {
222+ // :snippet-start: watch-for-changes
223+ val changeStream = collection.watch()
224+ changeStream.collect {
225+ println (" Change to ${it.fullDocument?.title} " )
226+ callCount + = 1 // :remove:
227+ }
228+ // :snippet-end:
229+ }
230+ delay(1 )
231+ collection.insertOne(Movie (" Shrek 5: Donkey's Revenge" , 2024 ))
232+ delay(1000 )
233+ job.cancel()
234+ assertEquals(1 , callCount)
235+ }
236+
237+ @Test
238+ fun accessDataFromFlowTest () = runBlocking {
239+ // :snippet-start: access-data-from-flow
240+ val flow = collection.find(
241+ Filters .eq(Movie ::year.name, 2004 )
242+ )
243+ flow.collect { println (it) }
244+ // :snippet-end:
245+ assertEquals(1 , flow.count())
246+ }
247+
248+ @Test
249+ fun accessResultsFromQueryAsListTest () = runBlocking {
250+
251+ val movies =
252+ // :snippet-start: access-results-from-query-as-list
253+ collection.find().toList()
254+ // :snippet-end:
255+ println (movies)
256+ assertEquals(4 , movies.size)
257+ }
258+
259+ @Test
260+ fun countDocumentsTest () = runBlocking {
261+
262+ val count =
263+ // :snippet-start: count-documents
264+ collection.countDocuments(Filters .eq(" year" , 2001 ))
265+ // :snippet-end:
266+ println (count)
267+ assertEquals(1 , count)
268+ }
269+
270+ @Test
271+ fun listDistinctDocumentsOrFieldValuesTest () = runBlocking {
272+ collection.insertMany(
273+ listOf (
274+ Movie (" Shrek 5: Farquaad Strikes Back" , 2026 , " PG" ),
275+ Movie (" Shrek 6: Rise of the Living Dead Ogres" , 2028 , " PG-13" )
276+ )
277+ )
278+ val distinctDocuments =
279+ // :snippet-start: list-distinct-documents-or-field-values
280+ collection.distinct<String >(Movie ::rated.name)
281+ // :snippet-end:
282+ println (distinctDocuments.toList())
283+ assertEquals(setOf (" PG" , " PG-13" , " Not Rated" ), distinctDocuments.toList().toSet())
284+ }
285+
286+ @Test
287+ fun limitNumberOfDocumentsTest () = runBlocking {
288+ val movies =
289+ // :snippet-start: limit-number-of-documents
290+ collection.find()
291+ .limit(2 )
292+ // :snippet-end:
293+ println (movies.toList())
294+ assertEquals(2 , movies.count())
295+ }
296+
297+ @Test
298+ fun skipDocumentsTest () = runBlocking {
299+ val movies =
300+ // :snippet-start: skip-documents
301+ collection.find()
302+ .skip(2 )
303+ // :snippet-end:
304+ println (movies.toList())
305+ assertEquals(2 , movies.count())
306+ }
307+
308+ @Test
309+ fun sortDocumentsTest () = runBlocking {
310+ val movies =
311+ // :snippet-start: sort-documents
312+ collection.find().sort(Sorts .descending(Movie ::year.name))
313+ // :snippet-end:
314+ println (movies.toList())
315+ assertEquals(2010 , movies.firstOrNull()?.year)
316+ }
317+
318+ @Test
319+ fun projectTest () = runBlocking {
320+ // :snippet-start: project
321+ data class Result (val title : String )
322+ // :remove-start:
323+ val movies =
324+ // :remove-end:
325+ collection.find<Result >()
326+ .projection(Projections .include(Movie ::title.name))
327+ // :snippet-end:
328+ val firstMovie = movies.firstOrNull()
329+ println (firstMovie)
330+ assertIs<Result >(firstMovie)
331+ Unit // added at the end to make the function not return internal type Result, which causes compiler to error
332+ }
333+
334+ @Test
335+ fun createIndexTest () = runBlocking {
336+ val indexName =
337+ // :snippet-start: create-index
338+ collection.createIndex(Indexes .ascending(Movie ::title.name))
339+ // :snippet-end:
340+ println (indexName)
341+ collection.dropIndex(indexName)
342+ assertEquals(" title_1" , indexName)
343+ }
344+
345+ @Test
346+ fun searchTextTest () = runBlocking {
347+ collection.createIndex(Indexes .text(Movie ::title.name))
348+ val movies =
349+ // :snippet-start: search-text
350+ collection.find(Filters .text(" Forever" ));
351+ // :snippet-end:
352+ println (movies.toList())
353+ assertEquals(1 , movies.count())
354+ }
355+ }
0 commit comments