Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BC-7794 - fix board link swap when copy course #5169

Merged
merged 2 commits into from
Aug 6, 2024
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { CourseRepo } from '@shared/repo/course/course.repo';
import { courseFactory, setupEntities, userDoFactory } from '@shared/testing';
import { CopyElementType, CopyStatus, CopyStatusEnum } from '@src/modules/copy-helper';
import { FilesStorageClientAdapterService } from '@src/modules/files-storage-client/service/files-storage-client.service';
import { BoardExternalReferenceType, ColumnBoard } from '../../domain';
import { BoardExternalReferenceType } from '../../domain';
import { columnBoardFactory } from '../../testing';
import { BoardNodeService } from '../board-node.service';
import { ColumnBoardCopyService } from './column-board-copy.service';
Expand All @@ -22,6 +22,7 @@ describe(ColumnBoardCopyService.name, () => {
let courseRepo: DeepMocked<CourseRepo>;
let userService: DeepMocked<UserService>;
let boardNodeCopyService: DeepMocked<BoardNodeCopyService>;
let columnBoardTitleService: DeepMocked<ColumnBoardTitleService>;

beforeAll(async () => {
module = await Test.createTestingModule({
Expand Down Expand Up @@ -51,6 +52,10 @@ describe(ColumnBoardCopyService.name, () => {
provide: FilesStorageClientAdapterService,
useValue: createMock<FilesStorageClientAdapterService>(),
},
{
provide: ColumnBoardTitleService,
useValue: createMock<ColumnBoardTitleService>(),
},
],
}).compile();

Expand All @@ -59,6 +64,7 @@ describe(ColumnBoardCopyService.name, () => {
courseRepo = module.get(CourseRepo);
userService = module.get(UserService);
boardNodeCopyService = module.get(BoardNodeCopyService);
columnBoardTitleService = module.get(ColumnBoardTitleService);

await setupEntities();
});
Expand All @@ -71,40 +77,183 @@ describe(ColumnBoardCopyService.name, () => {
await module.close();
});

const setup = () => {
const userId = new ObjectId().toHexString();
const user = userDoFactory.build({ id: userId });
userService.findById.mockResolvedValueOnce(user);
const course = courseFactory.buildWithId();
courseRepo.findById.mockResolvedValueOnce(course);
const originalBoard = columnBoardFactory.build({
context: { id: course.id, type: BoardExternalReferenceType.Course },
describe('copyColumnBoard', () => {
const setup = () => {
const userId = new ObjectId().toHexString();
const user = userDoFactory.build({ id: userId });
userService.findById.mockResolvedValueOnce(user);
const course = courseFactory.buildWithId();
courseRepo.findById.mockResolvedValueOnce(course);
const originalBoard = columnBoardFactory.build({
context: { id: course.id, type: BoardExternalReferenceType.Course },
});
boardNodeService.findByClassAndId.mockResolvedValueOnce(originalBoard);

const boardCopy = columnBoardFactory.build({
context: { id: course.id, type: BoardExternalReferenceType.Course },
});
const status: CopyStatus = {
copyEntity: boardCopy,
type: CopyElementType.BOARD,
status: CopyStatusEnum.SUCCESS,
};
boardNodeCopyService.copy.mockResolvedValueOnce(status);

return { originalBoard, userId };
};

it('should find the original board', async () => {
const { originalBoard, userId } = setup();

await service.copyColumnBoard({
originalColumnBoardId: originalBoard.id,
destinationExternalReference: originalBoard.context,
userId,
});

expect(boardNodeService.findByClassAndId).toHaveBeenCalled();
});

it('should find the user', async () => {
const { originalBoard, userId } = setup();

await service.copyColumnBoard({
originalColumnBoardId: originalBoard.id,
destinationExternalReference: originalBoard.context,
userId,
});

expect(userService.findById).toHaveBeenCalled();
});
boardNodeService.findByClassAndId.mockResolvedValueOnce(originalBoard);
const boardCopy = columnBoardFactory.build({
context: { id: course.id, type: BoardExternalReferenceType.Course },

it('should find the course', async () => {
const { originalBoard, userId } = setup();

await service.copyColumnBoard({
originalColumnBoardId: originalBoard.id,
destinationExternalReference: originalBoard.context,
userId,
});

expect(courseRepo.findById).toHaveBeenCalled();
});

it('should call service to copy the board', async () => {
const { originalBoard, userId } = setup();

await service.copyColumnBoard({
originalColumnBoardId: originalBoard.id,
destinationExternalReference: originalBoard.context,
userId,
copyTitle: 'Another Title',
});

expect(boardNodeCopyService.copy).toHaveBeenCalled();
});
const status: CopyStatus = {
copyEntity: boardCopy,
type: CopyElementType.BOARD,
status: CopyStatusEnum.SUCCESS,
};
boardNodeCopyService.copy.mockResolvedValueOnce(status);

return { originalBoard, userId };
};
it('should set the title of the copied board', async () => {
const { originalBoard, userId } = setup();
const copyTitle = 'Another Title';

it('should copy the board', async () => {
const { originalBoard, userId } = setup();
await service.copyColumnBoard({
originalColumnBoardId: originalBoard.id,
destinationExternalReference: originalBoard.context,
userId,
copyTitle,
});

const result = await service.copyColumnBoard({
originalColumnBoardId: originalBoard.id,
destinationExternalReference: originalBoard.context,
userId,
copyTitle: 'Another Title',
expect(boardNodeService.addRoot).toHaveBeenCalledWith(expect.objectContaining({ title: copyTitle }));
});

expect(boardNodeCopyService.copy).toHaveBeenCalled();
expect((result.copyEntity as ColumnBoard).title).toBe('Another Title');
it('should derive the title of the copied board', async () => {
const { originalBoard, userId } = setup();
const derivedTitle = 'Derived Title';
columnBoardTitleService.deriveColumnBoardTitle.mockResolvedValueOnce(derivedTitle);

await service.copyColumnBoard({
originalColumnBoardId: originalBoard.id,
destinationExternalReference: originalBoard.context,
userId,
});

expect(boardNodeService.addRoot).toHaveBeenCalledWith(expect.objectContaining({ title: derivedTitle }));
});

it('should set the context of the copied board', async () => {
const { originalBoard, userId } = setup();
const destinationExternalReference = {
id: new ObjectId().toHexString(),
type: BoardExternalReferenceType.Course,
};

await service.copyColumnBoard({
originalColumnBoardId: originalBoard.id,
destinationExternalReference,
userId,
});

expect(boardNodeService.addRoot).toHaveBeenCalledWith(
expect.objectContaining({ context: destinationExternalReference })
);
});

it('should return the copy status', async () => {
const { originalBoard, userId } = setup();
const copyStatus = await service.copyColumnBoard({
originalColumnBoardId: originalBoard.id,
destinationExternalReference: originalBoard.context,
userId,
});

expect(copyStatus).toBeDefined();
expect(copyStatus.copyEntity).toBeDefined();
});

it('should not affect the original board', async () => {
const { originalBoard, userId } = setup();
const copyStatus = await service.copyColumnBoard({
originalColumnBoardId: originalBoard.id,
destinationExternalReference: originalBoard.context,
userId,
});

expect(copyStatus.originalEntity).toBe(originalBoard);
});
});

describe('when the copy response is not a ColumnBoard', () => {
const setup = () => {
const userId = new ObjectId().toHexString();
const user = userDoFactory.build({ id: userId });
userService.findById.mockResolvedValueOnce(user);
const course = courseFactory.buildWithId();
courseRepo.findById.mockResolvedValueOnce(course);
const originalBoard = columnBoardFactory.build({
context: { id: course.id, type: BoardExternalReferenceType.Course },
});
boardNodeService.findByClassAndId.mockResolvedValueOnce(originalBoard);

return { originalBoard, userId };
};

it('should throw an error if the board is not a column board', async () => {
const { originalBoard, userId } = setup();

const boardCopy = { ...originalBoard, id: new ObjectId().toHexString(), type: 'not-a-column-board' };
const status: CopyStatus = {
copyEntity: boardCopy,
type: CopyElementType.BOARD,
status: CopyStatusEnum.SUCCESS,
};
boardNodeCopyService.copy.mockResolvedValueOnce(status);

await expect(
service.copyColumnBoard({
originalColumnBoardId: originalBoard.id,
destinationExternalReference: originalBoard.context,
userId,
})
).rejects.toThrowError('expected copy of columnboard to be a columnboard');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export class ColumnBoardCopyService {
}
copyStatus.copyEntity.context = props.destinationExternalReference;
await this.boardNodeService.addRoot(copyStatus.copyEntity);
copyStatus.originalEntity = originalBoard;

return copyStatus;
}
Expand Down
Loading