mirror of
https://github.com/standardnotes/server
synced 2026-10-19 00:03:11 -04:00
236 lines
8.3 KiB
TypeScript
236 lines
8.3 KiB
TypeScript
import 'reflect-metadata'
|
|
|
|
import { Logger } from 'winston'
|
|
import { User } from '../User/User'
|
|
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
|
|
import { RoleRepositoryInterface } from '../Role/RoleRepositoryInterface'
|
|
import { RoleName, SubscriptionName } from '@standardnotes/common'
|
|
import { Role } from '../Role/Role'
|
|
|
|
import { ClientServiceInterface } from '../Client/ClientServiceInterface'
|
|
import { RoleService } from './RoleService'
|
|
import { RoleToSubscriptionMapInterface } from './RoleToSubscriptionMapInterface'
|
|
import { OfflineUserSubscriptionRepositoryInterface } from '../Subscription/OfflineUserSubscriptionRepositoryInterface'
|
|
import { OfflineUserSubscription } from '../Subscription/OfflineUserSubscription'
|
|
import { PermissionName } from '@standardnotes/features'
|
|
import { Permission } from '../Permission/Permission'
|
|
|
|
describe('RoleService', () => {
|
|
let userRepository: UserRepositoryInterface
|
|
let roleRepository: RoleRepositoryInterface
|
|
let offlineUserSubscription: OfflineUserSubscription
|
|
let offlineUserSubscriptionRepository: OfflineUserSubscriptionRepositoryInterface
|
|
let roleToSubscriptionMap: RoleToSubscriptionMapInterface
|
|
let webSocketsClientService: ClientServiceInterface
|
|
let logger: Logger
|
|
let user: User
|
|
let basicRole: Role
|
|
let proRole: Role
|
|
|
|
const createService = () =>
|
|
new RoleService(
|
|
userRepository,
|
|
roleRepository,
|
|
offlineUserSubscriptionRepository,
|
|
webSocketsClientService,
|
|
roleToSubscriptionMap,
|
|
logger,
|
|
)
|
|
|
|
beforeEach(() => {
|
|
basicRole = {
|
|
name: RoleName.CoreUser,
|
|
permissions: Promise.resolve([
|
|
{
|
|
name: PermissionName.MarkdownBasicEditor,
|
|
} as jest.Mocked<Permission>,
|
|
]),
|
|
} as jest.Mocked<Role>
|
|
|
|
proRole = {
|
|
name: RoleName.ProUser,
|
|
permissions: Promise.resolve([
|
|
{
|
|
name: PermissionName.DailyEmailBackup,
|
|
} as jest.Mocked<Permission>,
|
|
]),
|
|
} as jest.Mocked<Role>
|
|
|
|
userRepository = {} as jest.Mocked<UserRepositoryInterface>
|
|
|
|
roleRepository = {} as jest.Mocked<RoleRepositoryInterface>
|
|
roleRepository.findOneByName = jest.fn().mockReturnValue(proRole)
|
|
|
|
roleToSubscriptionMap = {} as jest.Mocked<RoleToSubscriptionMapInterface>
|
|
roleToSubscriptionMap.getRoleNameForSubscriptionName = jest.fn().mockReturnValue(RoleName.ProUser)
|
|
|
|
offlineUserSubscription = {
|
|
endsAt: 100,
|
|
cancelled: false,
|
|
planName: SubscriptionName.ProPlan,
|
|
} as jest.Mocked<OfflineUserSubscription>
|
|
|
|
offlineUserSubscriptionRepository = {} as jest.Mocked<OfflineUserSubscriptionRepositoryInterface>
|
|
offlineUserSubscriptionRepository.findOneByEmail = jest.fn().mockReturnValue(offlineUserSubscription)
|
|
offlineUserSubscriptionRepository.save = jest.fn().mockReturnValue(offlineUserSubscription)
|
|
|
|
webSocketsClientService = {} as jest.Mocked<ClientServiceInterface>
|
|
webSocketsClientService.sendUserRolesChangedEvent = jest.fn()
|
|
|
|
logger = {} as jest.Mocked<Logger>
|
|
logger.info = jest.fn()
|
|
logger.warn = jest.fn()
|
|
})
|
|
|
|
describe('adding roles', () => {
|
|
beforeEach(() => {
|
|
user = {
|
|
uuid: '123',
|
|
email: '[email protected]',
|
|
roles: Promise.resolve([basicRole]),
|
|
} as jest.Mocked<User>
|
|
|
|
userRepository.findOneByEmail = jest.fn().mockReturnValue(user)
|
|
userRepository.save = jest.fn().mockReturnValue(user)
|
|
})
|
|
|
|
it('should add role to user', async () => {
|
|
await createService().addUserRole(user, SubscriptionName.ProPlan)
|
|
|
|
expect(roleRepository.findOneByName).toHaveBeenCalledWith(RoleName.ProUser)
|
|
user.roles = Promise.resolve([basicRole, proRole])
|
|
expect(userRepository.save).toHaveBeenCalledWith(user)
|
|
})
|
|
|
|
it('should not add duplicate role to user', async () => {
|
|
user = {
|
|
uuid: '123',
|
|
email: '[email protected]',
|
|
roles: Promise.resolve([basicRole, proRole]),
|
|
} as jest.Mocked<User>
|
|
|
|
userRepository.findOneByEmail = jest.fn().mockReturnValue(user)
|
|
|
|
await createService().addUserRole(user, SubscriptionName.ProPlan)
|
|
|
|
expect(roleRepository.findOneByName).toHaveBeenCalledWith(RoleName.ProUser)
|
|
expect(userRepository.save).toHaveBeenCalledWith(user)
|
|
expect(await user.roles).toHaveLength(2)
|
|
})
|
|
|
|
it('should send websockets event', async () => {
|
|
await createService().addUserRole(user, SubscriptionName.ProPlan)
|
|
|
|
expect(webSocketsClientService.sendUserRolesChangedEvent).toHaveBeenCalledWith(user)
|
|
})
|
|
|
|
it('should not add role if no role name exists for subscription name', async () => {
|
|
roleToSubscriptionMap.getRoleNameForSubscriptionName = jest.fn().mockReturnValue(undefined)
|
|
|
|
await createService().addUserRole(user, 'test' as SubscriptionName)
|
|
|
|
expect(userRepository.save).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('should not add role if no role exists for role name', async () => {
|
|
roleRepository.findOneByName = jest.fn().mockReturnValue(null)
|
|
await createService().addUserRole(user, SubscriptionName.ProPlan)
|
|
|
|
expect(userRepository.save).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('should set offline role to offline subscription', async () => {
|
|
await createService().setOfflineUserRole(offlineUserSubscription)
|
|
|
|
expect(roleRepository.findOneByName).toHaveBeenCalledWith(RoleName.ProUser)
|
|
expect(offlineUserSubscriptionRepository.save).toHaveBeenCalledWith({
|
|
endsAt: 100,
|
|
cancelled: false,
|
|
planName: SubscriptionName.ProPlan,
|
|
roles: Promise.resolve([proRole]),
|
|
})
|
|
})
|
|
|
|
it('should not set offline role if no role name exists for subscription name', async () => {
|
|
roleToSubscriptionMap.getRoleNameForSubscriptionName = jest.fn().mockReturnValue(undefined)
|
|
|
|
await createService().setOfflineUserRole(offlineUserSubscription)
|
|
|
|
expect(offlineUserSubscriptionRepository.save).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('should not set offline role if no role exists for role name', async () => {
|
|
roleRepository.findOneByName = jest.fn().mockReturnValue(null)
|
|
|
|
await createService().setOfflineUserRole(offlineUserSubscription)
|
|
|
|
expect(offlineUserSubscriptionRepository.save).not.toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
describe('removing roles', () => {
|
|
beforeEach(() => {
|
|
user = {
|
|
uuid: '123',
|
|
email: '[email protected]',
|
|
roles: Promise.resolve([basicRole, proRole]),
|
|
} as jest.Mocked<User>
|
|
|
|
userRepository.findOneByEmail = jest.fn().mockReturnValue(user)
|
|
userRepository.save = jest.fn().mockReturnValue(user)
|
|
})
|
|
|
|
it('should remove role from user', async () => {
|
|
await createService().removeUserRole(user, SubscriptionName.ProPlan)
|
|
|
|
expect(userRepository.save).toHaveBeenCalledWith(user)
|
|
})
|
|
|
|
it('should send websockets event', async () => {
|
|
await createService().removeUserRole(user, SubscriptionName.ProPlan)
|
|
|
|
expect(webSocketsClientService.sendUserRolesChangedEvent).toHaveBeenCalledWith(user)
|
|
})
|
|
|
|
it('should not remove role if role name does not exist for subscription name', async () => {
|
|
roleToSubscriptionMap.getRoleNameForSubscriptionName = jest.fn().mockReturnValue(undefined)
|
|
|
|
await createService().removeUserRole(user, 'test' as SubscriptionName)
|
|
|
|
expect(userRepository.save).not.toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
describe('checking permissions', () => {
|
|
beforeEach(() => {
|
|
user = {
|
|
uuid: '123',
|
|
email: '[email protected]',
|
|
roles: Promise.resolve([basicRole, proRole]),
|
|
} as jest.Mocked<User>
|
|
|
|
userRepository.findOneByUuid = jest.fn().mockReturnValue(user)
|
|
})
|
|
|
|
it('should indicate if a user has given permission', async () => {
|
|
const userHasPermission = await createService().userHasPermission('1-2-3', PermissionName.DailyEmailBackup)
|
|
|
|
expect(userHasPermission).toBeTruthy()
|
|
})
|
|
|
|
it('should indicate if a user does not have a given permission', async () => {
|
|
const userHasPermission = await createService().userHasPermission('1-2-3', PermissionName.DailyGDriveBackup)
|
|
|
|
expect(userHasPermission).toBeFalsy()
|
|
})
|
|
|
|
it('should indicate user does not have a permission if user could not be found', async () => {
|
|
userRepository.findOneByUuid = jest.fn().mockReturnValue(null)
|
|
|
|
const userHasPermission = await createService().userHasPermission('1-2-3', PermissionName.DailyGDriveBackup)
|
|
|
|
expect(userHasPermission).toBeFalsy()
|
|
})
|
|
})
|
|
})
|