Skip to content
Snippets Groups Projects
Commit 676440c2 authored by vijay Shedge's avatar vijay Shedge
Browse files

apis created

parent 5468ac86
Branches
No related tags found
No related merge requests found
node_modules
dist
.vscode
.env
zippy-parity-410718-1746d3ba3bdf.json
\ No newline at end of file
FROM node:20-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD [ "node" , "dist/main.js" ]
This diff is collapsed.
import { ObjectId } from "mongodb"
const getUserTransactionsSTUB = () => {
return {
id: "659c43ef5605c4ccf2eeaab9",
transactions: [
{
name: "test",
amount: 1299,
date: 1704725146285
}
]
}
}
export const AppService = jest.fn().mockReturnValue({
getHello: jest.fn().mockReturnValue("Hello World!"),
createUser: jest.fn().mockResolvedValue("user saved"),
setUserTransaction: jest.fn().mockResolvedValue("transaction saved"),
getUserTransactions: jest.fn().mockResolvedValue(getUserTransactionsSTUB()),
})
export const FileService = jest.fn().mockReturnValue({
upload: jest.fn().mockResolvedValue("File Uploaded"),
})
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { FileService } from './file.service';
jest.mock('./app.service')
jest.mock('./file.service')
describe('AppController', () => {
let appController: AppController;
let appService: AppService;
let fileService: FileService;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
providers: [AppService, FileService],
}).compile();
appService = app.get(AppService);
fileService = app.get(FileService);
appController = app.get<AppController>(AppController);
});
......@@ -19,4 +27,87 @@ describe('AppController', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
describe("createUser", () => {
describe("when user is called", () => {
let user = ""
let payload = {
name: "test"
}
beforeEach(async () => {
user = await appController.createUser(payload)
})
test("then it should call UserService", () => {
expect(appService.createUser).toHaveBeenCalledWith(payload)
})
test("then it should return user saved", () => {
expect(user).toBe("user saved")
})
})
})
describe("setTransactions", () => {
describe("when setTransactions is called", () => {
let user = ""
let payload = {
"id": "659c440f5605c4ccf2eeaacb",
"item": "item",
"date": "1704725146285",
"amount": 500
}
beforeEach(async () => {
user = await appController.setUserTransaction(payload)
})
test("then it should call UserService", () => {
expect(appService.setUserTransaction).toHaveBeenCalledWith(payload)
})
test("then it should return user saved", () => {
expect(user).toBe("transaction saved")
})
})
})
describe("getTransactions", () => {
describe("when setTransactions is called", () => {
let user;
let payload = {
"id": "659c43ef5605c4ccf2eeaab9",
"pageNo": 1,
"limit": 10,
"amount": 1700
} as any;
let returnData = {
id: "659c43ef5605c4ccf2eeaab9",
transactions: [
{
name: "test",
amount: 1299,
date: 1704725146285
}
]
}
beforeEach(async () => {
user = await appController.getUserTransaction(payload)
})
test("then it should call UserService", () => {
expect(appService.getUserTransactions).toHaveBeenCalledWith(payload)
})
test("then it should return user saved", () => {
expect(user).toEqual(returnData)
})
})
})
});
import { Controller, Get } from '@nestjs/common';
import { Body, Controller, Get, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { AppService } from './app.service';
import { User, GetUserTransaction } from './dtos/user.dto';
import { FileInterceptor } from '@nestjs/platform-express';
import { FileService } from './file.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
constructor(private readonly appService: AppService,
private readonly fileService: FileService
) { }
@Get()
getHello(): string {
getHello() {
return this.appService.getHello();
}
@Post('/createUser')
async createUser(@Body() payload: User) {
return await this.appService.createUser(payload)
}
@Post('/setUserTransaction')
async setUserTransaction(@Body() payload) {
return await this.appService.setUserTransaction(payload)
}
@Post('/getUserTransaction')
async getUserTransaction(@Body() payload: GetUserTransaction) {
return await this.appService.getUserTransactions(payload)
}
@Post('/upload')
@UseInterceptors(FileInterceptor('file'))
async uploadFile(@UploadedFile() file: Express.Multer.File) {
return await this.fileService.upload(file)
}
}
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';
import { MongooseModule } from '@nestjs/mongoose';
import { Users, UserSchema } from './models/user.model';
import { Transactions, TransactionSchema } from './models/transaction.model';
import { CacheModule } from '@nestjs/cache-manager';
import { RedisOptions } from './constants';
import { FileService } from './file.service';
@Module({
imports: [],
imports: [
ConfigModule.forRoot(),
CacheModule.registerAsync(RedisOptions),
// CacheModule.register(),
MongooseModule.forRoot(process.env.DB_URL),
MongooseModule.forFeature([
{ name: Users.name, schema: UserSchema },
{ name: Transactions.name, schema: TransactionSchema },
])
],
controllers: [AppController],
providers: [AppService],
providers: [AppService, FileService],
})
export class AppModule {}
import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Users } from './models/user.model';
import mongoose, { Model } from 'mongoose';
import { User, UserTransaction, GetUserTransaction } from './dtos/user.dto';
import { Transactions } from './models/transaction.model';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
constructor(@InjectModel(Users.name) private userModel: Model<Users>,
@InjectModel(Transactions.name) private transactionModel: Model<Transactions>,
@Inject(CACHE_MANAGER) private cacheManager: Cache
) { }
getHello() {
return "Hello World!"
}
async createUser(payload: User) {
const user = await this.userModel.create(payload)
await user.save();
return `user saved`
}
async setUserTransaction(payload: UserTransaction) {
const transaction = await this.transactionModel.create(payload);
await transaction.save();
const user = await this.userModel.findById(payload.id);
console.log(user)
user.transactions.push(transaction._id);
user.save();
return "transaction saved"
}
async getUserTransactions(payload: GetUserTransaction) {
const PAGE_LIMIT = payload.limit ?? 5;
const PAGE_NO = (payload.pageNo ?? 1);
const memCheck = await this.cacheManager.get(JSON.stringify(payload));
if (memCheck) {
return memCheck;
}
let match: any = {};
if (payload.date) {
match.date = payload.date
}
if (payload.amount) {
match.amount = payload.amount
}
let userDetails = (await this.userModel.findById(payload.id)).populate({
path: "transactions",
match: match,
options: {
skip: (PAGE_NO - 1) * PAGE_LIMIT,
limit: PAGE_LIMIT
}
});
// let userDetails = await this.userModel.aggregate([
// {
// $match: {
// _id: new mongoose.Types.ObjectId(payload.id)
// },
// },
// {
// $unwind: "$transactions"
// },
// {
// $lookup: {
// from: "transactions",
// localField: "transactions",
// foreignField: "_id",
// as: "transactions",
// }
// },
// {
// $skip: (PAGE_NO - 1) * PAGE_LIMIT
// },
// {
// $limit: PAGE_LIMIT
// },
// {
// $group: {
// _id: "$_id",
// transactionsList: {
// $push: {
// items: {
// $first: "$transactions"
// }
// }
// }
// }
// }
// ])
await this.cacheManager.set(JSON.stringify(payload), userDetails, { ttl: 5000 } as any);
return userDetails;
}
}
import { CacheModuleAsyncOptions } from "@nestjs/cache-manager";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { redisStore } from "cache-manager-redis-store";
export const RedisOptions: CacheModuleAsyncOptions = {
isGlobal: true,
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => {
const store = await redisStore({
socket: {
host: configService.get<string>('REDIS_HOST'),
port: parseInt(configService.get<string>('REDIS_PORT')),
},
ttl: 20000
});
return {
store: () => store,
};
},
inject: [ConfigService],
};
\ No newline at end of file
import { Types } from "mongoose";
export class User {
name: string;
transactions?: string[] = [""]
}
export interface UserTransaction {
id: Types.ObjectId;
item: string;
date: number;
amount: number;
}
export interface GetUserTransaction {
id: Types.ObjectId;
pageNo: number;
limit?: number;
date?: number;
amount?: number;
}
\ No newline at end of file
import { Injectable, InternalServerErrorException } from '@nestjs/common';
import { Storage } from '@google-cloud/storage'
import { join } from 'path';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class FileService {
constructor(private configService: ConfigService) { }
async upload(file: Express.Multer.File) {
// console.log(join(__dirname, `../${this.configService.get("GCP_BUCKET_CONFIG")}.json`))
const storage = new Storage({
keyFilename: join(__dirname, `../${this.configService.get("GCP_BUCKET_CONFIG")}.json`),
});
if(!storage) {
throw new InternalServerErrorException({
statusCode: -1,
error: "storage Iniitialize failed"
})
}
const bucketName = 'goodbucketname'
const bucket = storage.bucket(bucketName)
// Sending the upload request
const fileStream = bucket.file(file.originalname).createWriteStream();
fileStream.end(file.buffer)
const result = () => {
return new Promise((res, rej) => {
fileStream.on("finish", () => {
res("Done Processing image")
})
fileStream.on("error", (error) => {
console.log(error)
rej(error.message)
})
})
}
try {
await result();
return "File Uploaded"
} catch (error) {
throw new InternalServerErrorException({
statusCode: -1,
error: JSON.stringify(error?.stack ?? error)
})
}
}
}
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import mongoose, { HydratedDocument } from 'mongoose';
import { Users } from './user.model';
export type TransactionDocument = HydratedDocument<Transactions>;
@Schema()
export class Transactions {
@Prop({
type: mongoose.Schema.Types.ObjectId, ref: "Users"
})
user : Users;
@Prop({
required: true
})
item: string;
@Prop({
required: true
})
date: number;
@Prop({
required: true
})
amount: number;
}
export const TransactionSchema = SchemaFactory.createForClass(Transactions)
\ No newline at end of file
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import mongoose, { HydratedDocument, Types } from 'mongoose';
export type UsersDocument = HydratedDocument<Users>;
@Schema()
export class Users {
@Prop([{
type: mongoose.Schema.Types.ObjectId, ref: "Transactions",
}])
transactions: Types.ObjectId[];
@Prop({
required: true
})
name: string;
}
export const UserSchema = SchemaFactory.createForClass(Users)
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment