Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions apps/web/dao/user.dao.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { UserDao } from "./user.dao";
import UserModel from "@models/User";
import mongoose from "mongoose";

afterEach(async () => {
await UserModel.deleteMany({});
});

describe("UserDao", () => {
let userDao: UserDao;

beforeEach(() => {
userDao = new UserDao();
});

it("should create a user", async () => {
const userData = {
email: "[email protected]",
name: "Test User",
userId: "123",
unsubscribeToken: "token",
domain: new mongoose.Types.ObjectId().toString(),
};
const user = await userDao.createUser(userData);
expect(user).toBeDefined();
expect(user.email).toBe(userData.email);
});

it("should get a user by id", async () => {
const userData = {
email: "[email protected]",
name: "Test User",
userId: "123",
unsubscribeToken: "token",
domain: new mongoose.Types.ObjectId().toString(),
};
await userDao.createUser(userData);
const user = await userDao.getUserById("123", userData.domain);
expect(user).toBeDefined();
expect(user!.email).toBe(userData.email);
});

it("should get a user by email", async () => {
const userData = {
email: "[email protected]",
name: "Test User",
userId: "123",
unsubscribeToken: "token",
domain: new mongoose.Types.ObjectId().toString(),
};
await userDao.createUser(userData);
const user = await userDao.getUserByEmail("[email protected]", userData.domain);
expect(user).toBeDefined();
expect(user!.email).toBe(userData.email);
});

it("should update a user", async () => {
const userData = {
email: "[email protected]",
name: "Test User",
userId: "123",
unsubscribeToken: "token",
domain: new mongoose.Types.ObjectId().toString(),
};
await userDao.createUser(userData);
const updatedUser = await userDao.updateUser("123", userData.domain, {
name: "Updated Test User",
});
expect(updatedUser).toBeDefined();
expect(updatedUser!.name).toBe("Updated Test User");
});
});
155 changes: 155 additions & 0 deletions apps/web/dao/user.dao.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import { User } from "@courselit/common-models";
import UserModel from "@models/User";
import { makeModelTextSearchable } from "@/lib/graphql";

export interface IUserDao {
getUserById(userId: string, domainId: string): Promise<User | null>;
getUserByEmail(email: string, domainId: string): Promise<User | null>;
createUser(userData: Partial<User>): Promise<User>;
updateUser(
userId: string,
domainId: string,
userData: Partial<User>,
): Promise<User | null>;
find(query: any): Promise<User[]>;
findOne(query: any): Promise<User | null>;
findOneAndUpdate(
query: any,
update: any,
options: any,
): Promise<User | null>;
countDocuments(query: any): Promise<number>;
updateMany(query: any, update: any): Promise<any>;
aggregate(pipeline: any[]): Promise<any[]>;
deleteUser(userId: string, domainId: string): Promise<any>;
search(
{
offset,
query,
graphQLContext,
}: { offset: number; query: any; graphQLContext: any },
{
itemsPerPage,
sortByColumn,
sortOrder,
}: {
itemsPerPage: number;
sortByColumn: string;
sortOrder: number;
},
): Promise<User[]>;
}

export class UserDao implements IUserDao {
public async getUserById(
userId: string,
domainId: string,
): Promise<User | null> {
const user = await UserModel.findOne({
userId,
domain: domainId,
}).lean();
return user as User;
}

public async getUserByEmail(
email: string,
domainId: string,
): Promise<User | null> {
const user = await UserModel.findOne({
email,
domain: domainId,
}).lean();
return user as User;
}

public async createUser(userData: Partial<User>): Promise<User> {
const user = new UserModel(userData);
const newUser = await user.save();
return newUser.toObject();
}

public async updateUser(
userId: string,
domainId: string,
userData: Partial<User>,
): Promise<User | null> {
const user = await UserModel.findOneAndUpdate(
{ userId, domain: domainId },
{ $set: userData },
{ new: true },
).lean();
return user as User;
}

public async find(query: any): Promise<User[]> {
const users = await UserModel.find(query).lean();
return users as User[];
}

public async findOne(query: any): Promise<User | null> {
const user = await UserModel.findOne(query).lean();
return user as User;
}

public async findOneAndUpdate(
query: any,
update: any,
options: any,
): Promise<User | null> {
const user = await UserModel.findOneAndUpdate(
query,
update,
options,
).lean();
return user as User;
}

public async countDocuments(query: any): Promise<number> {
return await UserModel.countDocuments(query);
}

public async updateMany(query: any, update: any): Promise<any> {
return await UserModel.updateMany(query, update);
}

public async aggregate(pipeline: any[]): Promise<any[]> {
return await UserModel.aggregate(pipeline);
}

public async deleteUser(userId: string, domainId: string): Promise<any> {
return await UserModel.deleteOne({ userId, domain: domainId });
}

public async search(
{
offset,
query,
graphQLContext,
}: { offset: number; query: any; graphQLContext: any },
{
itemsPerPage,
sortByColumn,
sortOrder,
}: {
itemsPerPage: number;
sortByColumn: string;
sortOrder: number;
},
): Promise<User[]> {
const searchUsers = makeModelTextSearchable(UserModel);
const users = await searchUsers(
{
offset,
query,
graphQLContext,
},
{
itemsPerPage,
sortByColumn,
sortOrder,
},
);
return users.map((user: any) => user.toObject());
}
}
Loading