-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
317 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
import { JoinPolicy } from '@entities/room.entity'; | ||
import { TestAuthService } from '@fixtures/auth/test-auth-service'; | ||
import { TestMembershipsRepository } from '@fixtures/data/test.memberships.repository'; | ||
import { TestRoomsRepository } from '@fixtures/data/test.rooms.repository'; | ||
import { RoomFactory } from '@fixtures/messages/room.factory'; | ||
import { UserFactory } from '@fixtures/messages/user.factory'; | ||
import { UnauthorizedException } from '@nestjs/common'; | ||
import { AppLogger } from '@app/app.logger'; | ||
import { Role } from '@usecases/auth.service'; | ||
import mock, { MockProxy } from 'jest-mock-extended/lib/Mock'; | ||
import { Dispatcher } from '@entities/messages/message'; | ||
import { InviteUseCase } from './invite'; | ||
import { TestUsersRepository } from '@fixtures/data/test.users.repository'; | ||
import { MembershipStatus } from '@entities/membership.entity'; | ||
|
||
describe('InviteUseCase', () => { | ||
let invite: InviteUseCase; | ||
let rooms: TestRoomsRepository; | ||
let users: TestUsersRepository; | ||
let memberships: TestMembershipsRepository; | ||
let auth: TestAuthService; | ||
let dispatcher: MockProxy<Dispatcher>; | ||
|
||
const owner = UserFactory.build({ name: 'Alice' }); | ||
const otherUser = UserFactory.build({ name: 'Bob' }); | ||
const room = RoomFactory.build({ joinPolicy: JoinPolicy.Invite }); | ||
|
||
const now = new Date(1000); | ||
|
||
beforeEach(() => { | ||
rooms = new TestRoomsRepository(); | ||
rooms.setData([room]); | ||
|
||
users = new TestUsersRepository(); | ||
users.setData([owner, otherUser]); | ||
|
||
memberships = new TestMembershipsRepository(); | ||
|
||
auth = new TestAuthService(mock<AppLogger>()); | ||
auth.stubPermission({ user: owner, subject: room, action: Role.Manage }); | ||
|
||
dispatcher = mock<Dispatcher>(); | ||
|
||
invite = new InviteUseCase(rooms, users, memberships, auth, dispatcher); | ||
|
||
jest.useFakeTimers({ now }); | ||
}); | ||
|
||
it('invites a user to the room', async () => { | ||
await invite.exec({ | ||
authenticatedUser: owner, | ||
roomId: room.id, | ||
email: otherUser.email, | ||
}); | ||
|
||
expect(memberships.getData()).toEqual([ | ||
{ | ||
userId: otherUser.id, | ||
roomId: room.id, | ||
status: MembershipStatus.PendingInvite, | ||
from: now.getTime(), | ||
}, | ||
]); | ||
|
||
expect(dispatcher.send).toHaveBeenCalledWith({ | ||
content: 'Alice invited Bob to join the room', | ||
authorId: 'system', | ||
roomId: room.id, | ||
}); | ||
}); | ||
|
||
it('authorizes the user', async () => { | ||
await expect( | ||
invite.exec({ | ||
authenticatedUser: otherUser, | ||
roomId: room.id, | ||
email: otherUser.email, | ||
}), | ||
).rejects.toEqual( | ||
new UnauthorizedException( | ||
'You do not have permission to perform this action.', | ||
), | ||
); | ||
}); | ||
|
||
it('checks the user exists', async () => { | ||
await invite.exec({ | ||
authenticatedUser: owner, | ||
roomId: room.id, | ||
email: 'not-a-user@example.com', | ||
}); | ||
|
||
expect(dispatcher.send).toHaveBeenCalledWith({ | ||
content: 'No user exists with email not-a-user@example.com', | ||
authorId: 'system', | ||
roomId: room.id, | ||
recipientId: owner.id, | ||
}); | ||
}); | ||
|
||
it('checks the user is not already a member', async () => { | ||
await memberships.setData([ | ||
{ | ||
from: 0, | ||
roomId: room.id, | ||
userId: otherUser.id, | ||
status: MembershipStatus.Joined, | ||
}, | ||
]); | ||
|
||
await invite.exec({ | ||
authenticatedUser: owner, | ||
roomId: room.id, | ||
email: otherUser.email, | ||
}); | ||
|
||
expect(dispatcher.send).toHaveBeenCalledWith({ | ||
content: 'Bob is already a member of this room', | ||
authorId: 'system', | ||
roomId: room.id, | ||
recipientId: owner.id, | ||
}); | ||
}); | ||
|
||
it('checks the user doesn not already have an invite', async () => { | ||
await memberships.setData([ | ||
{ | ||
from: 0, | ||
roomId: room.id, | ||
userId: otherUser.id, | ||
status: MembershipStatus.PendingInvite, | ||
}, | ||
]); | ||
|
||
await invite.exec({ | ||
authenticatedUser: owner, | ||
roomId: room.id, | ||
email: otherUser.email, | ||
}); | ||
|
||
expect(dispatcher.send).toHaveBeenCalledWith({ | ||
content: 'Bob already has an invite to this room', | ||
authorId: 'system', | ||
roomId: room.id, | ||
recipientId: owner.id, | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { JoinPolicy } from '@entities/room.entity'; | ||
import { TestAuthService } from '@fixtures/auth/test-auth-service'; | ||
import { TestMembershipsRepository } from '@fixtures/data/test.memberships.repository'; | ||
import { TestRoomsRepository } from '@fixtures/data/test.rooms.repository'; | ||
import { RoomFactory } from '@fixtures/messages/room.factory'; | ||
import { UserFactory } from '@fixtures/messages/user.factory'; | ||
import { AppLogger } from '@app/app.logger'; | ||
import { Role } from '@usecases/auth.service'; | ||
import mock, { MockProxy } from 'jest-mock-extended/lib/Mock'; | ||
import { Dispatcher, UpdatedEntity } from '@entities/messages/message'; | ||
import { LeaveRoomUseCase } from './leave'; | ||
import { MembershipStatus } from '@entities/membership.entity'; | ||
|
||
describe('LeaveRoomUseCase', () => { | ||
let leave: LeaveRoomUseCase; | ||
let rooms: TestRoomsRepository; | ||
let memberships: TestMembershipsRepository; | ||
let auth: TestAuthService; | ||
let dispatcher: MockProxy<Dispatcher>; | ||
|
||
const user = UserFactory.build({ name: 'Joe Bloggs' }); | ||
|
||
const now = new Date(1000); | ||
|
||
beforeEach(() => { | ||
rooms = new TestRoomsRepository(); | ||
memberships = new TestMembershipsRepository(); | ||
auth = new TestAuthService(mock<AppLogger>()); | ||
dispatcher = mock<Dispatcher>(); | ||
leave = new LeaveRoomUseCase(rooms, memberships, dispatcher); | ||
jest.useFakeTimers({ now }); | ||
}); | ||
|
||
it('assigns a membership to the user', async () => { | ||
const room = RoomFactory.build({ | ||
joinPolicy: JoinPolicy.Anyone, | ||
}); | ||
rooms.setData([room]); | ||
auth.stubPermission({ user, subject: room, action: Role.Read }); | ||
|
||
await leave.exec({ authenticatedUser: user, roomId: room.id }); | ||
|
||
expect(memberships.getData()).toEqual([ | ||
{ | ||
userId: user.id, | ||
roomId: room.id, | ||
status: MembershipStatus.Revoked, | ||
from: now.getTime(), | ||
}, | ||
]); | ||
|
||
expect(dispatcher.send).toHaveBeenCalledWith({ | ||
content: 'Joe Bloggs left the room.', | ||
authorId: 'system', | ||
roomId: room.id, | ||
updatedEntities: [UpdatedEntity.Room, UpdatedEntity.Users], | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters