diff --git a/tests/auth.ts b/tests/auth.ts deleted file mode 100644 index 82a6a165..00000000 --- a/tests/auth.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { assert } from "./test.deps.ts"; -import { testWithClient } from "./common.ts"; -import { MongoClient } from "../src/client.ts"; - -const hostname = "127.0.0.1"; - -testWithClient("createUser", async (client) => { - const db = client.database("test"); - await db.createUser("user1", "y3mq3mpZ3J6PGfgg"); - await db.createUser("user2", "Qa6WkQSuXF425sWZ"); -}); - -Deno.test("connect authorization test 1 - test db", async () => { - var username = "user1"; - var password = "y3mq3mpZ3J6PGfgg"; - const client = new MongoClient(); - await client.connect( - `mongodb://${username}:${password}@${hostname}:27017/test`, - ); - const names = await client.listDatabases(); - assert(names instanceof Array); - assert(names.length > 0); - client.close(); -}); - -Deno.test("connect authorization test 2 - test db", async () => { - var username = "user2"; - var password = "Qa6WkQSuXF425sWZ"; - const client = new MongoClient(); - await client.connect( - `mongodb://${username}:${password}@${hostname}:27017/test`, - ); - const names = await client.listDatabases(); - assert(names instanceof Array); - assert(names.length > 0); - client.close(); -}); - -testWithClient("dropUser", async (client) => { - const db = client.database("test"); - await db.dropUser("user1"); - await db.dropUser("user2"); -}); diff --git a/tests/cases/00_uri.ts b/tests/cases/00_uri.ts new file mode 100644 index 00000000..62e17dfa --- /dev/null +++ b/tests/cases/00_uri.ts @@ -0,0 +1,141 @@ +import { parse } from "../../src/utils/uri.ts"; +import { assertEquals } from "./../test.deps.ts"; + +export default function uriTests() { + Deno.test({ + name: "should correctly parse mongodb://localhost", + fn() { + const options = parse("mongodb://localhost/"); + assertEquals(options.db, "admin"); + assertEquals(options.servers.length, 1); + assertEquals(options.servers[0].host, "localhost"); + assertEquals(options.servers[0].port, 27017); + }, + }); + + Deno.test({ + name: "should correctly parse mongodb://localhost:27017", + fn() { + const options = parse("mongodb://localhost:27017/"); + assertEquals(options.db, "admin"); + assertEquals(options.servers.length, 1); + assertEquals(options.servers[0].host, "localhost"); + assertEquals(options.servers[0].port, 27017); + }, + }); + + Deno.test({ + name: + "should correctly parse mongodb://localhost:27017/test?appname=hello%20world", + fn() { + const options = parse( + "mongodb://localhost:27017/test?appname=hello%20world", + ); + assertEquals(options.appname, "hello world"); + }, + }); + + Deno.test({ + name: + "should correctly parse mongodb://localhost/?safe=true&readPreference=secondary", + fn() { + const options = parse( + "mongodb://localhost/?safe=true&readPreference=secondary", + ); + assertEquals(options.db, "admin"); + assertEquals(options.servers.length, 1); + assertEquals(options.servers[0].host, "localhost"); + assertEquals(options.servers[0].port, 27017); + }, + }); + + Deno.test({ + name: "should correctly parse mongodb://localhost:28101/", + fn() { + const options = parse("mongodb://localhost:28101/"); + assertEquals(options.db, "admin"); + assertEquals(options.servers.length, 1); + assertEquals(options.servers[0].host, "localhost"); + assertEquals(options.servers[0].port, 28101); + }, + }); + Deno.test({ + name: "should correctly parse mongodb://fred:foobar@localhost/baz", + fn() { + const options = parse("mongodb://fred:foobar@localhost/baz"); + assertEquals(options.db, "baz"); + assertEquals(options.servers.length, 1); + assertEquals(options.servers[0].host, "localhost"); + assertEquals(options.credential!.username, "fred"); + assertEquals(options.credential!.password, "foobar"); + }, + }); + + Deno.test({ + name: "should correctly parse mongodb://fred:foo%20bar@localhost/baz", + fn() { + const options = parse("mongodb://fred:foo%20bar@localhost/baz"); + assertEquals(options.db, "baz"); + assertEquals(options.servers.length, 1); + assertEquals(options.servers[0].host, "localhost"); + assertEquals(options.credential!.username, "fred"); + assertEquals(options.credential!.password, "foo bar"); + }, + }); + + Deno.test({ + name: "should correctly parse mongodb://%2Ftmp%2Fmongodb-27017.sock", + fn() { + const options = parse("mongodb://%2Ftmp%2Fmongodb-27017.sock"); + assertEquals(options.servers.length, 1); + assertEquals(options.servers[0].domainSocket, "/tmp/mongodb-27017.sock"); + assertEquals(options.db, "admin"); + }, + }); + + Deno.test({ + name: + "should correctly parse mongodb://fred:foo@%2Ftmp%2Fmongodb-27017.sock", + fn() { + const options = parse("mongodb://fred:foo@%2Ftmp%2Fmongodb-27017.sock"); + assertEquals(options.servers.length, 1); + assertEquals(options.servers[0].domainSocket, "/tmp/mongodb-27017.sock"); + assertEquals(options.credential!.username, "fred"); + assertEquals(options.credential!.password, "foo"); + assertEquals(options.db, "admin"); + }, + }); + + Deno.test({ + name: + "should correctly parse mongodb://fred:foo@%2Ftmp%2Fmongodb-27017.sock/somedb", + fn() { + const options = parse( + "mongodb://fred:foo@%2Ftmp%2Fmongodb-27017.sock/somedb", + ); + assertEquals(options.servers.length, 1); + assertEquals(options.servers[0].domainSocket, "/tmp/mongodb-27017.sock"); + assertEquals(options.credential!.username, "fred"); + assertEquals(options.credential!.password, "foo"); + assertEquals(options.db, "somedb"); + }, + }); + + Deno.test({ + name: + "should correctly parse mongodb://fred:foo@%2Ftmp%2Fmongodb-27017.sock/somedb?safe=true", + fn() { + const options = parse( + "mongodb://fred:foo@%2Ftmp%2Fmongodb-27017.sock/somedb?safe=true", + ); + assertEquals(options.servers.length, 1); + assertEquals(options.servers[0].domainSocket, "/tmp/mongodb-27017.sock"); + assertEquals(options.credential!.username, "fred"); + assertEquals(options.credential!.password, "foo"); + assertEquals(options.db, "somedb"); + assertEquals(options.safe, true); + }, + }); + + // TODO: add more tests (https://github.com/mongodb/node-mongodb-native/blob/3.6/test/functional/url_parser.test.js) +} diff --git a/tests/cases/01_auth.ts b/tests/cases/01_auth.ts new file mode 100644 index 00000000..54f0e5f8 --- /dev/null +++ b/tests/cases/01_auth.ts @@ -0,0 +1,162 @@ +import { + cleanUsername, + clientFirstMessageBare, + HI, + passwordDigest, +} from "../../src/auth/mod.ts"; +import { MongoClient } from "../../src/client.ts"; +import { testWithClient } from "../common.ts"; +import { assert, assertEquals } from "../test.deps.ts"; + +const hostname = "127.0.0.1"; + +interface PasswordValid { + username: string; + password: string; + digest: string; +} + +const passwordValdis: PasswordValid[] = [ + { + username: "user", + password: "pencil", + digest: "1c33006ec1ffd90f9cadcbcc0e118200", + }, + { + username: "test", + password: "test", + digest: "a6de521abefc2fed4f5876855a3484f5", + }, +]; + +export default function authTests() { + passwordValdis.forEach(({ username, password, digest }) => { + Deno.test({ + name: `passwordDigest:${username}:${password}`, + fn() { + const digestRes: string = passwordDigest(username, password); + assertEquals(digestRes, digest); + }, + }); + }); + + Deno.test({ + name: "clientFirstMessageBare", + fn() { + const username = "1234"; + const nonce = new TextEncoder().encode("qwer"); + const result: Uint8Array = clientFirstMessageBare(username, nonce); + const expected: Uint8Array = Uint8Array.from( + [ + 110, + 61, + 49, + 50, + 51, + 52, + 44, + 114, + 61, + 99, + 88, + 100, + 108, + 99, + 103, + 61, + 61, + ], + ); + assertEquals(expected, result); + }, + }); + + Deno.test({ + name: "cleanUsername", + fn() { + const username: string = "first=12,last=34"; + const expected: string = "first=3D12=2Clast=34"; + const result: string = cleanUsername(username); + assertEquals(expected, result); + }, + }); + + const salt = "rQ9ZY3MntBeuP3E1TDVC4w"; + const iter = 10000; + const data = "1c33006ec1ffd90f9cadcbcc0e118200"; + + Deno.test({ + name: "HI", + fn() { + const saltedPassword = HI( + data, + (new TextEncoder()).encode(salt), + iter, + "sha1", + ); + assertEquals( + saltedPassword, + [ + 72, + 84, + 156, + 182, + 17, + 64, + 30, + 116, + 86, + 233, + 7, + 39, + 65, + 137, + 142, + 164, + 0, + 110, + 78, + 230, + ], + ); + }, + }); + + testWithClient("createUser", async (client) => { + const db = client.database("test"); + await db.createUser("user1", "y3mq3mpZ3J6PGfgg"); + await db.createUser("user2", "Qa6WkQSuXF425sWZ"); + }); + + Deno.test("connect authorization test 1 - test db", async () => { + var username = "user1"; + var password = "y3mq3mpZ3J6PGfgg"; + const client = new MongoClient(); + await client.connect( + `mongodb://${username}:${password}@${hostname}:27017/test`, + ); + const names = await client.listDatabases(); + assert(names instanceof Array); + assert(names.length > 0); + client.close(); + }); + + Deno.test("connect authorization test 2 - test db", async () => { + var username = "user2"; + var password = "Qa6WkQSuXF425sWZ"; + const client = new MongoClient(); + await client.connect( + `mongodb://${username}:${password}@${hostname}:27017/test`, + ); + const names = await client.listDatabases(); + assert(names instanceof Array); + assert(names.length > 0); + client.close(); + }); + + testWithClient("dropUser", async (client) => { + const db = client.database("test"); + await db.dropUser("user1"); + await db.dropUser("user2"); + }); +} diff --git a/tests/cases/02_connect.ts b/tests/cases/02_connect.ts new file mode 100644 index 00000000..42d5c86b --- /dev/null +++ b/tests/cases/02_connect.ts @@ -0,0 +1,27 @@ +import { assert } from "../test.deps.ts"; +import { MongoClient } from "../../src/client.ts"; + +const hostname = "127.0.0.1"; + +export default function connectTests() { + Deno.test("test connect", async () => { + const client = new MongoClient(); + await client.connect(`mongodb://${hostname}:27017`); + const names = await client.listDatabases(); + assert(names instanceof Array); + assert(names.length > 0); + client.close(); + }); + + Deno.test("testconnect With Options", async () => { + const client = new MongoClient(); + await client.connect({ + servers: [{ host: hostname, port: 27017 }], + db: "admin", + }); + const names = await client.listDatabases(); + assert(names instanceof Array); + assert(names.length > 0); + client.close(); + }); +} diff --git a/tests/cases/03_curd.ts b/tests/cases/03_curd.ts new file mode 100644 index 00000000..6e7ec41c --- /dev/null +++ b/tests/cases/03_curd.ts @@ -0,0 +1,305 @@ +import { testWithClient } from "../common.ts"; +import { assert, assertEquals, assertThrowsAsync } from "../test.deps.ts"; + +interface IUser { + username: string; + password: string; + _id: { $oid: string }; + uid?: number; + date?: Date; +} + +const dateNow = Date.now(); + +export default function curdTests() { + testWithClient("testListCollectionNames", async (client) => { + const db = client.database("local"); + const names = await db.listCollectionNames(); + assertEquals(names, ["startup_log"]); + }); + + testWithClient("testInsertOne", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const insertId = await users.insertOne({ + username: "user1", + password: "pass1", + date: new Date(dateNow), + }); + + assertEquals(insertId.toString().length, 24); + + const user1 = await users.findOne({ + _id: insertId, + }); + + assertEquals(user1, { + _id: insertId, + username: "user1", + password: "pass1", + date: new Date(dateNow), + }); + }); + + testWithClient("testUpsertOne", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const { upsertedId } = await users.updateOne( + { _id: "aaaaaaaaaaaaaaaaaaaaaaaa" }, + { + username: "user1", + password: "pass1", + date: new Date(dateNow), + }, + { upsert: true }, + ); + + assert(upsertedId); + + const user1 = await users.findOne({ + _id: upsertedId, + }); + + assertEquals(user1, { + _id: upsertedId, + username: "user1", + password: "pass1", + date: new Date(dateNow), + }); + }); + + testWithClient("testInsertOneTwice", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users_2"); + await users.insertOne({ + _id: "aaaaaaaaaaaaaaaaaaaaaaaa", + username: "user1", + }); + + await assertThrowsAsync( + () => + users.insertOne({ + _id: "aaaaaaaaaaaaaaaaaaaaaaaa", + username: "user1", + }) as any, + undefined, + "E11000", + ); + }); + + testWithClient("testFindOne", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const user1 = await users.findOne(); + assertEquals(Object.keys(user1!), ["_id", "username", "password", "date"]); + + const query = { test: 1 }; + const findNull = await users.findOne(query); + assertEquals(findNull, undefined); + const projectionUser = await users.findOne( + {}, + { projection: { _id: 0, username: 1 } }, + ); + assertEquals(Object.keys(projectionUser!), ["username"]); + const projectionUserWithId = await users.findOne( + {}, + { projection: { username: 1 } }, + ); + assertEquals(Object.keys(projectionUserWithId!), ["_id", "username"]); + }); + + testWithClient("testInsertMany", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const { insertedCount, insertedIds } = await users.insertMany([ + { + username: "many", + password: "pass1", + }, + { + username: "many", + password: "pass2", + }, + ]); + + assertEquals(insertedCount, 2); + assertEquals(insertedIds.length, 2); + }); + + testWithClient("test chain call for Find", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const user = await users.find().skip(1).limit(1).toArray(); + assertEquals(user!.length > 0, true); + }); + + testWithClient("testUpdateOne", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const result = await users.updateOne({}, { username: "USER1" }); + assertEquals(result, { + matchedCount: 1, + modifiedCount: 1, + upsertedCount: 0, + upsertedId: undefined, + }); + }); + + testWithClient("testUpdateOneWithUpsert", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const result = await users.updateOne( + { username: "user2" }, + { username: "USER2" }, + { upsert: true }, + ); + assertEquals(result.matchedCount, 1); + assertEquals(result.modifiedCount, 0); + assertEquals(result.upsertedCount, 1); + }); + + testWithClient("testDeleteOne", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const deleteCount = await users.deleteOne({}); + assertEquals(deleteCount, 1); + }); + + testWithClient("testFindOr", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const user1 = await users + .find({ + $or: [{ password: "pass1" }, { password: "pass2" }], + }) + .toArray(); + assert(user1 instanceof Array); + assertEquals(user1.length, 3); + }); + + testWithClient("testFind", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const findUsers = await users + .find({ username: "many" }, { skip: 1, limit: 1 }) + .toArray(); + assert(findUsers instanceof Array); + assertEquals(findUsers.length, 1); + + const notFound = await users.find({ test: 1 }).toArray(); + assertEquals(notFound, []); + }); + + testWithClient("testCount", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const count = await users.count({ username: "many" }); + assertEquals(count, 2); + }); + + testWithClient("testAggregation", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const docs = await users + .aggregate([ + { $match: { username: "many" } }, + { $group: { _id: "$username", total: { $sum: 1 } } }, + ]) + .toArray(); + assertEquals(docs, [{ _id: "many", total: 2 }]); + }); + + testWithClient("testUpdateMany", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const result = await users.updateMany( + { username: "many" }, + { $set: { username: "MANY" } }, + ); + assertEquals(result, { + matchedCount: 2, + modifiedCount: 2, + upsertedCount: 0, + upsertedIds: undefined, + }); + }); + + testWithClient("testDeleteMany", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const deleteCount = await users.deleteMany({ username: "MANY" }); + assertEquals(deleteCount, 2); + }); + + testWithClient("testDistinct", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const user1 = await users.distinct("username"); + assertEquals(user1, ["USER2", "user1"]); + }); + + // // TODO mongdb_rust official library has not implemented this feature + // // testWithClient("testCreateIndexes", async (client) => { + // // const db = client.database("test"); + // // const collection = db.collection("mongo_indexes"); + // // const result = await collection.createIndexes([ + // // { keys: { created_at: 1 }, options: { expireAfterSeconds: 10000 } } + // // ]); + // // console.log(result); + // // }); + + testWithClient("testDropConnection", async (client) => { + const db = client.database("test"); + await db.collection("mongo_test_users_2").drop(); + await db.collection("mongo_test_users").drop(); + }); + + testWithClient("testFindWithSort", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + + const condition = { uid: { $ne: null } }; + + // prepare data + for (let i = 0; i < 10; i++) { + await users.insertOne({ + username: "testFindWithSort", + password: "pass1", + uid: i, + }); + } + const all = await users.find().toArray(); + + // test sorting + const acceding = await users + .find(condition, { sort: { uid: 1 } }) + .toArray(); + const descending = await users + .find(condition, { sort: { uid: -1 } }) + .toArray(); + + assertEquals( + acceding, + all.sort((lhs, rhs) => { + return lhs.uid! - rhs.uid!; + }), + ); + assertEquals( + descending, + all.sort((lhs, rhs) => { + return -lhs.uid! - rhs.uid!; + }), + ); + }); + + testWithClient("testFindEmptyAsyncIteration", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const cursor = users.find({ nonexistent: "foo" }); + const docs = []; + for await (const doc of cursor) { + docs.push(doc); + } + assertEquals(docs, []); + }); +} diff --git a/tests/cases/04_indexes.ts b/tests/cases/04_indexes.ts new file mode 100644 index 00000000..ee6269ee --- /dev/null +++ b/tests/cases/04_indexes.ts @@ -0,0 +1,38 @@ +import { testWithClient } from "../common.ts"; +import { assertEquals } from "../test.deps.ts"; + +export default function indexesTests() { + testWithClient("createIndexes", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const res = await users.createIndexes({ + indexes: [{ + name: "_name", + key: { name: 1 }, + }], + }); + assertEquals( + res, + { + createdCollectionAutomatically: false, + numIndexesBefore: 1, + numIndexesAfter: 2, + ok: 1, + }, + ); + }); + + testWithClient("listIndexes", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const cursor = users.listIndexes(); + const indexes = await cursor.toArray(); + assertEquals( + indexes, + [ + { v: 2, key: { _id: 1 }, name: "_id_", ns: "test.mongo_test_users" }, + { v: 2, key: { name: 1 }, name: "_name", ns: "test.mongo_test_users" }, + ], + ); + }); +} diff --git a/tests/cases/99_cleanup.ts b/tests/cases/99_cleanup.ts new file mode 100644 index 00000000..b851210b --- /dev/null +++ b/tests/cases/99_cleanup.ts @@ -0,0 +1,12 @@ +import { testWithClient } from "../common.ts"; + +export default function cleanup() { + testWithClient("cleanup", async (client) => { + const db = client.database("test"); + try { + await db.collection("mongo_test_users_2").drop().catch((e) => e); + await db.collection("mongo_test_users").drop().catch((e) => e); + } catch { + } + }); +} diff --git a/tests/common.ts b/tests/common.ts index 9521c538..95b17552 100644 --- a/tests/common.ts +++ b/tests/common.ts @@ -2,7 +2,7 @@ import { MongoClient } from "../mod.ts"; const hostname = "127.0.0.1"; -export async function testWithClient( +export function testWithClient( name: string, fn: (client: MongoClient) => void | Promise, ) { @@ -18,8 +18,3 @@ async function getClient(): Promise { await client.connect(`mongodb://${hostname}:27017`); return client; } - -export async function cheanup() { - const db = (await getClient()).database("test"); - await db.collection("mongo_test_users").drop(); -} diff --git a/tests/connect.ts b/tests/connect.ts deleted file mode 100644 index ed099aea..00000000 --- a/tests/connect.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { assert } from "./test.deps.ts"; -import { MongoClient } from "../src/client.ts"; - -const hostname = "127.0.0.1"; - -Deno.test("test connect", async () => { - const client = new MongoClient(); - await client.connect(`mongodb://${hostname}:27017`); - const names = await client.listDatabases(); - assert(names instanceof Array); - assert(names.length > 0); - client.close(); -}); - -Deno.test("testconnect With Options", async () => { - const client = new MongoClient(); - await client.connect({ - servers: [{ host: hostname, port: 27017 }], - db: "admin", - }); - const names = await client.listDatabases(); - assert(names instanceof Array); - assert(names.length > 0); - client.close(); -}); diff --git a/tests/curd.ts b/tests/curd.ts deleted file mode 100644 index 0dbb3677..00000000 --- a/tests/curd.ts +++ /dev/null @@ -1,303 +0,0 @@ -import { testWithClient } from "./common.ts"; -import { assert, assertEquals, assertThrowsAsync } from "./test.deps.ts"; - -interface IUser { - username: string; - password: string; - _id: { $oid: string }; - uid?: number; - date?: Date; -} - -const dateNow = Date.now(); - -await testWithClient("testListCollectionNames", async (client) => { - const db = client.database("local"); - const names = await db.listCollectionNames(); - assertEquals(names, ["startup_log"]); -}); - -await testWithClient("testInsertOne", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const insertId = await users.insertOne({ - username: "user1", - password: "pass1", - date: new Date(dateNow), - }); - - assertEquals(insertId.toString().length, 24); - - const user1 = await users.findOne({ - _id: insertId, - }); - - assertEquals(user1, { - _id: insertId, - username: "user1", - password: "pass1", - date: new Date(dateNow), - }); -}); - -testWithClient("testUpsertOne", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const { upsertedId } = await users.updateOne( - { _id: "aaaaaaaaaaaaaaaaaaaaaaaa" }, - { - username: "user1", - password: "pass1", - date: new Date(dateNow), - }, - { upsert: true }, - ); - - assert(upsertedId); - - const user1 = await users.findOne({ - _id: upsertedId, - }); - - assertEquals(user1, { - _id: upsertedId, - username: "user1", - password: "pass1", - date: new Date(dateNow), - }); -}); - -testWithClient("testInsertOneTwice", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users_2"); - await users.insertOne({ - _id: "aaaaaaaaaaaaaaaaaaaaaaaa", - username: "user1", - }); - - await assertThrowsAsync( - () => - users.insertOne({ - _id: "aaaaaaaaaaaaaaaaaaaaaaaa", - username: "user1", - }) as any, - undefined, - "E11000", - ); -}); - -await testWithClient("testFindOne", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const user1 = await users.findOne(); - assertEquals(Object.keys(user1!), ["_id", "username", "password", "date"]); - - const query = { test: 1 }; - const findNull = await users.findOne(query); - assertEquals(findNull, undefined); - const projectionUser = await users.findOne( - {}, - { projection: { _id: 0, username: 1 } }, - ); - assertEquals(Object.keys(projectionUser!), ["username"]); - const projectionUserWithId = await users.findOne( - {}, - { projection: { username: 1 } }, - ); - assertEquals(Object.keys(projectionUserWithId!), ["_id", "username"]); -}); - -testWithClient("testInsertMany", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const { insertedCount, insertedIds } = await users.insertMany([ - { - username: "many", - password: "pass1", - }, - { - username: "many", - password: "pass2", - }, - ]); - - assertEquals(insertedCount, 2); - assertEquals(insertedIds.length, 2); -}); - -await testWithClient("test chain call for Find", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const user = await users.find().skip(1).limit(1).toArray(); - assertEquals(user!.length > 0, true); -}); - -testWithClient("testUpdateOne", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const result = await users.updateOne({}, { username: "USER1" }); - assertEquals(result, { - matchedCount: 1, - modifiedCount: 1, - upsertedCount: 0, - upsertedId: undefined, - }); -}); - -testWithClient("testUpdateOneWithUpsert", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const result = await users.updateOne( - { username: "user2" }, - { username: "USER2" }, - { upsert: true }, - ); - assertEquals(result.matchedCount, 1); - assertEquals(result.modifiedCount, 0); - assertEquals(result.upsertedCount, 1); -}); - -testWithClient("testDeleteOne", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const deleteCount = await users.deleteOne({}); - assertEquals(deleteCount, 1); -}); - -testWithClient("testFindOr", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const user1 = await users - .find({ - $or: [{ password: "pass1" }, { password: "pass2" }], - }) - .toArray(); - assert(user1 instanceof Array); - assertEquals(user1.length, 3); -}); - -testWithClient("testFind", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const findUsers = await users - .find({ username: "many" }, { skip: 1, limit: 1 }) - .toArray(); - assert(findUsers instanceof Array); - assertEquals(findUsers.length, 1); - - const notFound = await users.find({ test: 1 }).toArray(); - assertEquals(notFound, []); -}); - -testWithClient("testCount", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const count = await users.count({ username: "many" }); - assertEquals(count, 2); -}); - -testWithClient("testAggregation", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const docs = await users - .aggregate([ - { $match: { username: "many" } }, - { $group: { _id: "$username", total: { $sum: 1 } } }, - ]) - .toArray(); - assertEquals(docs, [{ _id: "many", total: 2 }]); -}); - -testWithClient("testUpdateMany", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const result = await users.updateMany( - { username: "many" }, - { $set: { username: "MANY" } }, - ); - assertEquals(result, { - matchedCount: 2, - modifiedCount: 2, - upsertedCount: 0, - upsertedIds: undefined, - }); -}); - -testWithClient("testDeleteMany", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const deleteCount = await users.deleteMany({ username: "MANY" }); - assertEquals(deleteCount, 2); -}); - -testWithClient("testDistinct", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const user1 = await users.distinct("username"); - assertEquals(user1, ["USER2", "user1"]); -}); - -// // TODO mongdb_rust official library has not implemented this feature -// // testWithClient("testCreateIndexes", async (client) => { -// // const db = client.database("test"); -// // const collection = db.collection("mongo_indexes"); -// // const result = await collection.createIndexes([ -// // { keys: { created_at: 1 }, options: { expireAfterSeconds: 10000 } } -// // ]); -// // console.log(result); -// // }); - -testWithClient("testDropConnection", async (client) => { - const db = client.database("test"); - await db.collection("mongo_test_users_2").drop(); - await db.collection("mongo_test_users").drop(); -}); - -testWithClient("testFindWithSort", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - - const condition = { uid: { $ne: null } }; - - // prepare data - for (let i = 0; i < 10; i++) { - await users.insertOne({ - username: "testFindWithSort", - password: "pass1", - uid: i, - }); - } - const all = await users.find().toArray(); - - // test sorting - const acceding = await users - .find(condition, { sort: { uid: 1 } }) - .toArray(); - const descending = await users - .find(condition, { sort: { uid: -1 } }) - .toArray(); - - assertEquals( - acceding, - all.sort((lhs, rhs) => { - return lhs.uid! - rhs.uid!; - }), - ); - assertEquals( - descending, - all.sort((lhs, rhs) => { - return -lhs.uid! - rhs.uid!; - }), - ); -}); - -testWithClient("testFindEmptyAsyncIteration", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const cursor = users.find({ nonexistent: "foo" }); - const docs = []; - for await (const doc of cursor) { - docs.push(doc); - } - assertEquals(docs, []); -}); diff --git a/tests/indexes.ts b/tests/indexes.ts deleted file mode 100644 index b2554140..00000000 --- a/tests/indexes.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { testWithClient } from "./common.ts"; -import { assertEquals } from "./test.deps.ts"; - -testWithClient("createIndexes", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const res = await users.createIndexes({ - indexes: [{ - name: "_name", - key: { name: 1 }, - }], - }); - assertEquals( - res, - { - createdCollectionAutomatically: true, - numIndexesBefore: 1, - numIndexesAfter: 2, - ok: 1, - }, - ); -}); - -testWithClient("listIndexes", async (client) => { - const db = client.database("test"); - const users = db.collection("mongo_test_users"); - const cursor = users.listIndexes(); - const indexes = await cursor.toArray(); - assertEquals( - indexes, - [ - { v: 2, key: { _id: 1 }, name: "_id_", ns: "test.mongo_test_users" }, - { v: 2, key: { name: 1 }, name: "_name", ns: "test.mongo_test_users" }, - ], - ); -}); diff --git a/tests/test.ts b/tests/test.ts index 31842c48..61bdb7f2 100644 --- a/tests/test.ts +++ b/tests/test.ts @@ -1,10 +1,14 @@ -import "./auth.ts"; -import { cheanup } from "./common.ts"; -import "./connect.ts"; -import "./curd.ts"; -import "./indexes.ts"; -import "./utils/auth/auth.ts"; -import "./utils/auth/HI.ts"; -import "./utils/uri.ts"; +import uriTests from "./cases/00_uri.ts"; +import authTests from "./cases/01_auth.ts"; +import connectTests from "./cases/02_connect.ts"; +import curdTests from "./cases/03_curd.ts"; +import indexesTests from "./cases/04_indexes.ts"; +import cleanup from "./cases/99_cleanup.ts"; -await cheanup(); +uriTests(); +authTests(); +connectTests(); +curdTests(); +indexesTests(); + +cleanup(); diff --git a/tests/utils/auth/HI.ts b/tests/utils/auth/HI.ts deleted file mode 100644 index 5305a065..00000000 --- a/tests/utils/auth/HI.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { HI } from "../../../src/auth/mod.ts"; -import { assertEquals } from "../../test.deps.ts"; - -const salt = "rQ9ZY3MntBeuP3E1TDVC4w"; -const iter = 10000; -const data = "1c33006ec1ffd90f9cadcbcc0e118200"; - -Deno.test({ - name: "HI", - fn() { - const saltedPassword = HI( - data, - (new TextEncoder()).encode(salt), - iter, - "sha1", - ); - assertEquals( - saltedPassword, - [ - 72, - 84, - 156, - 182, - 17, - 64, - 30, - 116, - 86, - 233, - 7, - 39, - 65, - 137, - 142, - 164, - 0, - 110, - 78, - 230, - ], - ); - }, -}); diff --git a/tests/utils/auth/auth.ts b/tests/utils/auth/auth.ts deleted file mode 100644 index 96d32c60..00000000 --- a/tests/utils/auth/auth.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { - cleanUsername, - clientFirstMessageBare, - passwordDigest, -} from "../../../src/auth/mod.ts"; -import { assertEquals } from "../../test.deps.ts"; - -interface PasswordValid { - username: string; - password: string; - digest: string; -} - -const passwordValdis: PasswordValid[] = [ - { - username: "user", - password: "pencil", - digest: "1c33006ec1ffd90f9cadcbcc0e118200", - }, - { - username: "test", - password: "test", - digest: "a6de521abefc2fed4f5876855a3484f5", - }, -]; -passwordValdis.forEach(({ username, password, digest }) => { - Deno.test({ - name: `passwordDigest:${username}:${password}`, - fn() { - const digestRes: string = passwordDigest(username, password); - assertEquals(digestRes, digest); - }, - }); -}); - -Deno.test({ - name: "clientFirstMessageBare", - fn() { - const username = "1234"; - const nonce = new TextEncoder().encode("qwer"); - const result: Uint8Array = clientFirstMessageBare(username, nonce); - const expected: Uint8Array = Uint8Array.from( - [110, 61, 49, 50, 51, 52, 44, 114, 61, 99, 88, 100, 108, 99, 103, 61, 61], - ); - assertEquals(expected, result); - }, -}); - -Deno.test({ - name: "cleanUsername", - fn() { - const username: string = "first=12,last=34"; - const expected: string = "first=3D12=2Clast=34"; - const result: string = cleanUsername(username); - assertEquals(expected, result); - }, -}); diff --git a/tests/utils/uri.ts b/tests/utils/uri.ts deleted file mode 100644 index 76ddf850..00000000 --- a/tests/utils/uri.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { parse } from "../../src/utils/uri.ts"; -import { assertEquals } from "../test.deps.ts"; - -Deno.test({ - name: "should correctly parse mongodb://localhost", - fn() { - const options = parse("mongodb://localhost/"); - assertEquals(options.db, "admin"); - assertEquals(options.servers.length, 1); - assertEquals(options.servers[0].host, "localhost"); - assertEquals(options.servers[0].port, 27017); - }, -}); - -Deno.test({ - name: "should correctly parse mongodb://localhost:27017", - fn() { - const options = parse("mongodb://localhost:27017/"); - assertEquals(options.db, "admin"); - assertEquals(options.servers.length, 1); - assertEquals(options.servers[0].host, "localhost"); - assertEquals(options.servers[0].port, 27017); - }, -}); - -Deno.test({ - name: - "should correctly parse mongodb://localhost:27017/test?appname=hello%20world", - fn() { - const options = parse( - "mongodb://localhost:27017/test?appname=hello%20world", - ); - assertEquals(options.appname, "hello world"); - }, -}); - -Deno.test({ - name: - "should correctly parse mongodb://localhost/?safe=true&readPreference=secondary", - fn() { - const options = parse( - "mongodb://localhost/?safe=true&readPreference=secondary", - ); - assertEquals(options.db, "admin"); - assertEquals(options.servers.length, 1); - assertEquals(options.servers[0].host, "localhost"); - assertEquals(options.servers[0].port, 27017); - }, -}); - -Deno.test({ - name: "should correctly parse mongodb://localhost:28101/", - fn() { - const options = parse("mongodb://localhost:28101/"); - assertEquals(options.db, "admin"); - assertEquals(options.servers.length, 1); - assertEquals(options.servers[0].host, "localhost"); - assertEquals(options.servers[0].port, 28101); - }, -}); -Deno.test({ - name: "should correctly parse mongodb://fred:foobar@localhost/baz", - fn() { - const options = parse("mongodb://fred:foobar@localhost/baz"); - assertEquals(options.db, "baz"); - assertEquals(options.servers.length, 1); - assertEquals(options.servers[0].host, "localhost"); - assertEquals(options.credential!.username, "fred"); - assertEquals(options.credential!.password, "foobar"); - }, -}); - -Deno.test({ - name: "should correctly parse mongodb://fred:foo%20bar@localhost/baz", - fn() { - const options = parse("mongodb://fred:foo%20bar@localhost/baz"); - assertEquals(options.db, "baz"); - assertEquals(options.servers.length, 1); - assertEquals(options.servers[0].host, "localhost"); - assertEquals(options.credential!.username, "fred"); - assertEquals(options.credential!.password, "foo bar"); - }, -}); - -Deno.test({ - name: "should correctly parse mongodb://%2Ftmp%2Fmongodb-27017.sock", - fn() { - const options = parse("mongodb://%2Ftmp%2Fmongodb-27017.sock"); - assertEquals(options.servers.length, 1); - assertEquals(options.servers[0].domainSocket, "/tmp/mongodb-27017.sock"); - assertEquals(options.db, "admin"); - }, -}); - -Deno.test({ - name: "should correctly parse mongodb://fred:foo@%2Ftmp%2Fmongodb-27017.sock", - fn() { - const options = parse("mongodb://fred:foo@%2Ftmp%2Fmongodb-27017.sock"); - assertEquals(options.servers.length, 1); - assertEquals(options.servers[0].domainSocket, "/tmp/mongodb-27017.sock"); - assertEquals(options.credential!.username, "fred"); - assertEquals(options.credential!.password, "foo"); - assertEquals(options.db, "admin"); - }, -}); - -Deno.test({ - name: - "should correctly parse mongodb://fred:foo@%2Ftmp%2Fmongodb-27017.sock/somedb", - fn() { - const options = parse( - "mongodb://fred:foo@%2Ftmp%2Fmongodb-27017.sock/somedb", - ); - assertEquals(options.servers.length, 1); - assertEquals(options.servers[0].domainSocket, "/tmp/mongodb-27017.sock"); - assertEquals(options.credential!.username, "fred"); - assertEquals(options.credential!.password, "foo"); - assertEquals(options.db, "somedb"); - }, -}); - -Deno.test({ - name: - "should correctly parse mongodb://fred:foo@%2Ftmp%2Fmongodb-27017.sock/somedb?safe=true", - fn() { - const options = parse( - "mongodb://fred:foo@%2Ftmp%2Fmongodb-27017.sock/somedb?safe=true", - ); - assertEquals(options.servers.length, 1); - assertEquals(options.servers[0].domainSocket, "/tmp/mongodb-27017.sock"); - assertEquals(options.credential!.username, "fred"); - assertEquals(options.credential!.password, "foo"); - assertEquals(options.db, "somedb"); - assertEquals(options.safe, true); - }, -}); -// TODO: add more tests (https://github.com/mongodb/node-mongodb-native/blob/3.6/test/functional/url_parser.test.js)