Skip to content

Commit 19b4965

Browse files
Merge pull request #22 from MaximumTrainer/copilot/add-where-clause-support
feat: add WHERE clause test coverage for MongoDB and Azure SQL connectors
2 parents 950fe75 + 7b6b3c9 commit 19b4965

2 files changed

Lines changed: 141 additions & 0 deletions

File tree

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.opendatamask.connector
2+
3+
import org.junit.jupiter.api.BeforeEach
4+
import org.junit.jupiter.api.Test
5+
import org.junit.jupiter.api.Assertions.*
6+
7+
class AzureSQLConnectorTest {
8+
9+
// Use H2 in MSSQLServer compatibility mode with null credentials so
10+
// AzureSQLConnector takes the simple DriverManager.getConnection(url) path.
11+
private val h2Url =
12+
"jdbc:h2:mem:aztest_${System.nanoTime()};DB_CLOSE_DELAY=-1;MODE=MSSQLServer;DATABASE_TO_UPPER=FALSE"
13+
private lateinit var connector: AzureSQLConnector
14+
15+
@BeforeEach
16+
fun setup() {
17+
connector = AzureSQLConnector(h2Url, null, null)
18+
java.sql.DriverManager.getConnection(h2Url).use { conn ->
19+
conn.createStatement().execute(
20+
"CREATE TABLE IF NOT EXISTS test_users (id INT, name VARCHAR(100), email VARCHAR(200))"
21+
)
22+
conn.createStatement().execute("DELETE FROM test_users")
23+
conn.createStatement().execute("INSERT INTO test_users VALUES (1, 'Alice', 'alice@example.com')")
24+
conn.createStatement().execute("INSERT INTO test_users VALUES (2, 'Bob', 'bob@example.com')")
25+
}
26+
}
27+
28+
@Test
29+
fun `testConnection returns true for valid connection`() {
30+
assertTrue(connector.testConnection())
31+
}
32+
33+
@Test
34+
fun `fetchData returns all rows without limit or filter`() {
35+
val rows = connector.fetchData("test_users")
36+
assertEquals(2, rows.size)
37+
}
38+
39+
@Test
40+
fun `fetchData respects row limit`() {
41+
val rows = connector.fetchData("test_users", limit = 1)
42+
assertEquals(1, rows.size)
43+
}
44+
45+
@Test
46+
fun `fetchData with whereClause filters rows`() {
47+
val rows = connector.fetchData("test_users", whereClause = "name = 'Alice'")
48+
assertEquals(1, rows.size)
49+
val name = rows[0]["NAME"] ?: rows[0]["name"]
50+
assertEquals("Alice", name)
51+
}
52+
53+
@Test
54+
fun `writeData inserts rows and returns count`() {
55+
val rows = listOf(
56+
mapOf("id" to 3, "name" to "Charlie", "email" to "charlie@example.com")
57+
)
58+
val count = connector.writeData("test_users", rows)
59+
assertEquals(1, count)
60+
val all = connector.fetchData("test_users")
61+
assertEquals(3, all.size)
62+
}
63+
64+
@Test
65+
fun `writeData returns 0 for empty list`() {
66+
assertEquals(0, connector.writeData("test_users", emptyList()))
67+
}
68+
69+
@Test
70+
fun `truncateTable removes all rows`() {
71+
connector.truncateTable("test_users")
72+
val rows = connector.fetchData("test_users")
73+
assertTrue(rows.isEmpty())
74+
}
75+
}

backend/src/test/kotlin/com/opendatamask/connector/MongoDBConnectorTest.kt

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package com.opendatamask.connector
22

3+
import com.mongodb.client.FindIterable
34
import com.mongodb.client.MongoClient
45
import com.mongodb.client.MongoCollection
56
import com.mongodb.client.MongoDatabase
67
import org.bson.Document
78
import org.junit.jupiter.api.Test
89
import org.junit.jupiter.api.Assertions.*
10+
import org.mockito.Mockito
911
import org.mockito.kotlin.*
1012

1113
class MongoDBConnectorTest {
@@ -16,6 +18,70 @@ class MongoDBConnectorTest {
1618
}
1719
}
1820

21+
/**
22+
* Returns a FindIterable mock that uses RETURNS_DEEP_STUBS so that the
23+
* MongoIterable.map(...).toList() call chain in fetchData() works without NPE.
24+
* fetchData() will return an empty list, but the filter/limit arguments
25+
* passed to find()/limit() can still be verified.
26+
*/
27+
private fun mockFindIterable(): FindIterable<Document> {
28+
val iterable = mock<FindIterable<Document>>(defaultAnswer = Mockito.RETURNS_DEEP_STUBS)
29+
whenever(iterable.limit(any<Int>())).thenReturn(iterable)
30+
return iterable
31+
}
32+
33+
@Test
34+
fun `fetchData uses empty filter when no whereClause provided`() {
35+
val mockCollection = mock<MongoCollection<Document>>()
36+
val mockDb = mock<MongoDatabase>()
37+
val mockClient = mock<MongoClient>()
38+
val findIterable = mockFindIterable()
39+
40+
whenever(mockClient.getDatabase("testdb")).thenReturn(mockDb)
41+
whenever(mockDb.getCollection("users")).thenReturn(mockCollection)
42+
whenever(mockCollection.find(any<Document>())).thenReturn(findIterable)
43+
44+
val connector = createConnector(mockClient)
45+
connector.fetchData("users")
46+
47+
verify(mockCollection).find(Document())
48+
}
49+
50+
@Test
51+
fun `fetchData applies JSON filter when whereClause provided`() {
52+
val mockCollection = mock<MongoCollection<Document>>()
53+
val mockDb = mock<MongoDatabase>()
54+
val mockClient = mock<MongoClient>()
55+
val findIterable = mockFindIterable()
56+
val expectedFilter = Document.parse("""{"age": 18}""")
57+
58+
whenever(mockClient.getDatabase("testdb")).thenReturn(mockDb)
59+
whenever(mockDb.getCollection("users")).thenReturn(mockCollection)
60+
whenever(mockCollection.find(any<Document>())).thenReturn(findIterable)
61+
62+
val connector = createConnector(mockClient)
63+
connector.fetchData("users", whereClause = """{"age": 18}""")
64+
65+
verify(mockCollection).find(expectedFilter)
66+
}
67+
68+
@Test
69+
fun `fetchData applies limit when specified`() {
70+
val mockCollection = mock<MongoCollection<Document>>()
71+
val mockDb = mock<MongoDatabase>()
72+
val mockClient = mock<MongoClient>()
73+
val findIterable = mockFindIterable()
74+
75+
whenever(mockClient.getDatabase("testdb")).thenReturn(mockDb)
76+
whenever(mockDb.getCollection("users")).thenReturn(mockCollection)
77+
whenever(mockCollection.find(any<Document>())).thenReturn(findIterable)
78+
79+
val connector = createConnector(mockClient)
80+
connector.fetchData("users", limit = 5)
81+
82+
verify(findIterable).limit(5)
83+
}
84+
1985
@Test
2086
fun `writeData calls insertMany and returns row count`() {
2187
val mockCollection = mock<MongoCollection<Document>>()

0 commit comments

Comments
 (0)