Skip to content

Commit

Permalink
refactor(api): Use existing Redis provider in cache module
Browse files Browse the repository at this point in the history
  • Loading branch information
Z-xus committed Jul 29, 2024
1 parent dbdb568 commit 9f6aa76
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 28 deletions.
15 changes: 14 additions & 1 deletion apps/api/src/auth/controller/auth.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { GithubOAuthStrategyFactory } from '../../config/factory/github/github-s
import { GoogleOAuthStrategyFactory } from '../../config/factory/google/google-strategy.factory'
import { GitlabOAuthStrategyFactory } from '../../config/factory/gitlab/gitlab-strategy.factory'
import { CacheService } from '../../cache/cache.service'
import { REDIS_CLIENT } from '../../provider/redis.provider'

describe('AuthController', () => {
let controller: AuthController
Expand All @@ -27,7 +28,19 @@ describe('AuthController', () => {
{ provide: MAIL_SERVICE, useClass: MockMailService },
JwtService,
PrismaService,
CacheService
CacheService,
{
provide: REDIS_CLIENT,
useValue: {
publisher: {
setEx: jest.fn(),
set: jest.fn(),
get: jest.fn(),
del: jest.fn(),
keys: jest.fn()
}
}
}
]
})
.overrideProvider(PrismaService)
Expand Down
15 changes: 14 additions & 1 deletion apps/api/src/auth/service/auth.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { JwtService } from '@nestjs/jwt'
import { PrismaService } from '../../prisma/prisma.service'
import { mockDeep } from 'jest-mock-extended'
import { CacheService } from '../../cache/cache.service'
import { REDIS_CLIENT } from '../../provider/redis.provider'

describe('AuthService', () => {
let service: AuthService
Expand All @@ -17,7 +18,19 @@ describe('AuthService', () => {
{ provide: MAIL_SERVICE, useClass: MockMailService },
JwtService,
PrismaService,
CacheService
CacheService,
{
provide: REDIS_CLIENT,
useValue: {
publisher: {
setEx: jest.fn(),
set: jest.fn(),
get: jest.fn(),
del: jest.fn(),
keys: jest.fn()
}
}
}
]
})
.overrideProvider(PrismaService)
Expand Down
18 changes: 17 additions & 1 deletion apps/api/src/cache/cache.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
import { Test, TestingModule } from '@nestjs/testing'
import { CacheService } from './cache.service'
import { REDIS_CLIENT } from '../provider/redis.provider'

describe('CacheService', () => {
let service: CacheService

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [CacheService]
providers: [
CacheService,
{
provide: REDIS_CLIENT,
useValue: {
publisher: {
// Add minimal mock methods as needed
setEx: jest.fn(),
set: jest.fn(),
get: jest.fn(),
del: jest.fn(),
keys: jest.fn()
}
}
}
]
}).compile()

service = module.get<CacheService>(CacheService)
Expand Down
40 changes: 15 additions & 25 deletions apps/api/src/cache/cache.service.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
import { Injectable, Logger, OnModuleDestroy } from '@nestjs/common'
import { createClient, RedisClientType } from 'redis'
import { Inject, Injectable, OnModuleDestroy } from '@nestjs/common'
import { RedisClientType } from 'redis'
import { User } from '@prisma/client'
import { REDIS_CLIENT } from '../provider/redis.provider'

@Injectable()
export class CacheService implements OnModuleDestroy {
private readonly redisClient: RedisClientType
private static readonly USER_PREFIX = 'user-'
private readonly logger = new Logger(CacheService.name)

constructor() {
if (process.env.REDIS_URL) {
this.redisClient = createClient({
url: process.env.REDIS_URL
})
this.redisClient.connect().catch((error) => {
this.logger.error('Failed to connect to Redis', error)
})
} else {
this.logger.warn(
'REDIS_URL is not set. CacheService will not be functional.'
)
}
}
constructor(
@Inject(REDIS_CLIENT) private redisClient: { publisher: RedisClientType }
) {}

private getUserKey(userId: string): string {
return `${CacheService.USER_PREFIX}${userId}`
Expand All @@ -31,15 +19,15 @@ export class CacheService implements OnModuleDestroy {
const key = this.getUserKey(user.id)
const userJson = JSON.stringify(user)
if (expirationInSeconds) {
await this.redisClient.setEx(key, expirationInSeconds, userJson)
await this.redisClient.publisher.setEx(key, expirationInSeconds, userJson)
} else {
await this.redisClient.set(key, userJson)
await this.redisClient.publisher.set(key, userJson)
}
}

async getUser(userId: string): Promise<User | null> {
const key = this.getUserKey(userId)
const userData = await this.redisClient.get(key)
const userData = await this.redisClient.publisher.get(key)
if (userData) {
return JSON.parse(userData) as User
}
Expand All @@ -48,17 +36,19 @@ export class CacheService implements OnModuleDestroy {

async deleteUser(userId: string): Promise<number> {
const key = this.getUserKey(userId)
return await this.redisClient.del(key)
return await this.redisClient.publisher.del(key)
}

async clearAllUserCache(): Promise<void> {
const keys = await this.redisClient.keys(`${CacheService.USER_PREFIX}*`)
const keys = await this.redisClient.publisher.keys(
`${CacheService.USER_PREFIX}*`
)
if (keys.length > 0) {
await this.redisClient.del(keys)
await this.redisClient.publisher.del(keys)
}
}

async onModuleDestroy() {
await this.redisClient.quit()
await this.redisClient.publisher.quit()
}
}

0 comments on commit 9f6aa76

Please sign in to comment.