Add tests

This commit is contained in:
Aelita4 2024-06-01 15:58:57 +02:00
parent 24ed526cb6
commit cdcd3d69b3
Signed by: Aelita4
GPG Key ID: E44490C2025906C1
8 changed files with 4462 additions and 16 deletions

12
jest.config.cjs Normal file
View File

@ -0,0 +1,12 @@
require('dotenv').config()
module.exports = {
preset: 'ts-jest',
transform: {
'^.+\\.(ts|tsx)?$': 'ts-jest',
'^.+\\.(js|jsx)$': 'babel-jest',
},
testEnvironment: 'node',
rootDir: '.',
testMatch: ['<rootDir>/test/**/*.test.ts'],
};

4270
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,14 @@
{ {
"name": "", "name": "",
"type": "module", "type": "commonjs",
"version": "0.0.1", "version": "0.0.1",
"scripts": { "scripts": {
"dev": "astro dev", "dev": "astro dev",
"start": "astro dev", "start": "astro dev",
"build": "astro build", "build": "astro build",
"preview": "astro preview", "preview": "astro preview",
"astro": "astro" "astro": "astro",
"test": "jest --detectOpenHandles --silent=false --verbose=true"
}, },
"dependencies": { "dependencies": {
"@iconify-json/mdi": "^1.1.64", "@iconify-json/mdi": "^1.1.64",
@ -15,5 +16,12 @@
"astro": "^4.5.10", "astro": "^4.5.10",
"astro-icon": "^1.1.0", "astro-icon": "^1.1.0",
"mongodb": "^6.2.0" "mongodb": "^6.2.0"
},
"devDependencies": {
"@types/jest": "^29.5.12",
"dotenv": "^16.4.5",
"jest": "^29.7.0",
"ts-jest": "^29.1.4",
"ts-node": "^10.9.2"
} }
} }

View File

@ -1,22 +1,28 @@
import { MongoClient } from "mongodb"; import { MongoClient } from "mongodb";
if(!import.meta.env.MONGODB_URI || !import.meta.env.MONGODB_DB) {
throw new Error("Please define MONGODB_URI and MONGODB_DB environment variables inside .env"); if(!process.env.MONGODB_URI || !process.env.MONGODB_DB) {
throw new Error("Please define MONGODB_URI and MONGODB_DB environment variables inside .env");
} }
const uri = import.meta.env.MONGODB_URI; const uri = process.env.MONGODB_URI;
const dbName = import.meta.env.MONGODB_DB; const dbName = process.env.MONGODB_DB;
const options = {}; const options = {};
const connect = async () => { const mongo = new MongoClient(uri, options);
const mongo = await new MongoClient(uri, options).connect();
return mongo.db(dbName); export const connect = async () => {
await mongo.connect();
// return mongo.db(dbName);
}
export const disconnect = async () => {
mongo.close();
} }
export const getDB = async () => { export const getDB = async () => {
const mongo = await connect(); await connect();
return mongo; return mongo.db(dbName);
} }
export const Users = async () => { export const Users = async () => {
@ -27,4 +33,9 @@ export const Users = async () => {
export const AccessTokens = async () => { export const AccessTokens = async () => {
const db = await getDB(); const db = await getDB();
return db.collection('accessTokens'); return db.collection('accessTokens');
}
export const Planets = async () => {
const db = await getDB();
return db.collection('planets');
} }

View File

@ -1,4 +1,4 @@
import { Users } from '../db/mongodb'; import { Planets, Users } from '../db/mongodb';
import type User from '../../types/User'; import type User from '../../types/User';
import type Resources from '../../types/Resources'; import type Resources from '../../types/Resources';
import type Building from '../../types/Building'; import type Building from '../../types/Building';
@ -34,6 +34,11 @@ export const createUser = async (username: string, email: string, password: stri
return newUser; return newUser;
} }
export const deleteUser = async (id: ObjectId) => {
const users = await Users();
return users.deleteOne({ _id: id });
}
export const getUserById = async (id: ObjectId) => { export const getUserById = async (id: ObjectId) => {
const users = await Users(); const users = await Users();
return users.findOne({ return users.findOne({
@ -145,4 +150,29 @@ export const createOrUpgradeShip = async (user: User, ship: Ship) => {
{ $push: { ships: ship } } { $push: { ships: ship } }
); );
} }
}
export const getUserWithPlanets = async (id: ObjectId): Promise<User | null> => {
const users = await Users();
const planets = await Planets();
const rawUser = await users.findOne({
_id: id
})
if (!rawUser) return null;
const userPlanets = (await planets.find({
owner: id
}).toArray()).map(planet => {
planet.owner = rawUser;
return planet;
});
rawUser.planets = {
partial: false,
data: userPlanets
}
return rawUser as User;
} }

31
test/database.test.ts Normal file
View File

@ -0,0 +1,31 @@
import { createUser, deleteUser, getUserByNickOrEmail } from '../src/lib/db/users';
import { connect, disconnect } from '../src/lib/db/mongodb';
import { verify } from 'argon2';
beforeEach(async () => {
await connect();
});
afterEach(async () => {
await disconnect();
});
describe('Test user database functions', () => {
test('getUserByNickOrEmail', async () => {
const user = await getUserByNickOrEmail("gargamel");
expect(user).not.toBeNull();
expect(user?.username).toBe("gargamel");
expect(user?.email).toBe("gargamel@smerfy.pl");
});
test('createAndVerifyUser', async () => {
await createUser("test", "test@example.com", "password");
const user = await getUserByNickOrEmail("test");
expect(user).not.toBeNull();
if(!user) return;
expect(user?.username).toBe("test");
expect(user?.email).toBe("test@example.com");
expect(await verify(user?.password as string, "password")).toBe(true);
await deleteUser(user._id);
});
});

View File

@ -0,0 +1,85 @@
import { connect, disconnect } from "../src/lib/db/mongodb";
import { createUser, deleteUser } from "../src/lib/db/users";
import { calculateCurrentAvailableResources, getUserResources, updateUserResources } from "../src/lib/utils/resourceManager";
import User from "../src/types/User";
let user: User;
describe('Test resource manager', () => {
beforeEach(async () => {
await connect();
user = await createUser("test", "test@example.com", "password");
});
afterEach(async () => {
await deleteUser(user._id);
await disconnect();
});
describe('Test initial resources amount', () => {
test('initialResourcesAmount', async () => {
const resources = await getUserResources(user._id);
let i = 1;
resources.forEach(res => {
expect(res.amount).toBe(i * 11);
expect(res.perHourMiningRate).toBe(i * 11);
i++;
});
});
});
describe('Test calculation of available resources', () => {
test('calculationOfAvailableResources', async () => {
const resources = await getUserResources(user._id);
resources.forEach(res => {
res.amount = 0;
res.lastUpdated = new Date(Date.now() - 1000 * 60 * 60);
});
await updateUserResources(user._id, resources);
const availableResources = await calculateCurrentAvailableResources(user._id);
let i = 1;
availableResources.forEach(res => {
expect(res.amount).toBeCloseTo(i * 11);
i++;
});
const resourcesAfter = await getUserResources(user._id);
i = 1;
resourcesAfter.forEach(res => {
expect(res.amount).toBeCloseTo(i * 11);
i++;
});
});
});
describe('Test taking resources', () => {
test('takingResources', async () => {
const resources = await getUserResources(user._id);
resources.forEach(res => {
res.amount = 10_000;
});
let i = 1;
resources.forEach(res => {
res.amount -= i * 100;
i++;
});
await updateUserResources(user._id, resources);
const resourcesAfter = await getUserResources(user._id);
i = 1;
resourcesAfter.forEach(res => {
expect(res.amount).toBeCloseTo(10_000 - i * 100);
i++;
});
});
});
});

View File

@ -1,3 +1,8 @@
{ {
"extends": "astro/tsconfigs/strict" "extends": "astro/tsconfigs/strict",
"compilerOptions": {
"verbatimModuleSyntax": false,
"module": "ES2022",
"moduleResolution": "node"
}
} }