Skip to content

Commit

Permalink
BC-7794 - fix board link swap when copy course (#5169)
Browse files Browse the repository at this point in the history
  • Loading branch information
virgilchiriac committed Aug 6, 2024
1 parent eb914aa commit 1498b6c
Show file tree
Hide file tree
Showing 2 changed files with 179 additions and 29 deletions.
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

0 comments on commit 1498b6c

Please sign in to comment.