test: revise and expand block update tests

This commit is contained in:
medchedli 2025-06-11 19:07:27 +01:00
parent 629a07fef8
commit 3e1a20bfc8

View File

@ -7,7 +7,7 @@
*/
import { MongooseModule, getModelToken } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Model, Types } from 'mongoose';
import {
blockFixtures,
@ -204,6 +204,43 @@ describe('BlockRepository', () => {
expect(blockRepository.find).toHaveBeenCalled();
expect(blockRepository.updateOne).not.toHaveBeenCalled();
});
it('should handle circular references within moved blocks', async () => {
const blockA = {
id: 'blockA',
nextBlocks: ['blockB'],
attachedBlock: null,
} as Block;
const blockB = {
id: 'blockB',
nextBlocks: ['blockA'],
attachedBlock: null,
} as Block;
const movedBlocks = [blockA, blockB];
const movedBlockIds = movedBlocks.map((b) => b.id);
jest.spyOn(blockRepository, 'find').mockResolvedValue(movedBlocks);
const mockUpdateOne = jest
.spyOn(blockRepository, 'updateOne')
.mockResolvedValue({} as any);
await blockRepository.prepareBlocksInCategoryUpdateScope(
'new-category',
movedBlockIds,
);
expect(mockUpdateOne).toHaveBeenCalledWith('blockA', {
nextBlocks: ['blockB'],
attachedBlock: null,
});
expect(mockUpdateOne).toHaveBeenCalledWith('blockB', {
nextBlocks: ['blockA'],
attachedBlock: null,
});
expect(mockUpdateOne).toHaveBeenCalledTimes(2);
});
});
describe('prepareBlocksOutOfCategoryUpdateScope', () => {
@ -212,16 +249,15 @@ describe('BlockRepository', () => {
{
id: blockValidIds[1],
attachedBlock: blockValidIds[0],
nextBlocks: [blockValidIds[0]],
nextBlocks: [],
},
] as Block[];
] as unknown as Block[];
const mockUpdateOne = jest.spyOn(blockRepository, 'updateOne');
await blockRepository.prepareBlocksOutOfCategoryUpdateScope(
otherBlocks,
blockValidIds,
);
await blockRepository.prepareBlocksOutOfCategoryUpdateScope(otherBlocks, [
blockValidIds[0],
]);
expect(mockUpdateOne).toHaveBeenCalledWith(blockValidIds[1], {
attachedBlock: null,
@ -233,7 +269,7 @@ describe('BlockRepository', () => {
{
id: blockValidIds[1],
attachedBlock: null,
nextBlocks: [blockValidIds[0], blockValidIds[1]],
nextBlocks: [blockValidIds[0], blockValidIds[2]],
},
] as unknown as Block[];
@ -244,29 +280,58 @@ describe('BlockRepository', () => {
]);
expect(mockUpdateOne).toHaveBeenCalledWith(blockValidIds[1], {
nextBlocks: [blockValidIds[1]],
nextBlocks: [blockValidIds[2]],
});
});
it('should not update blocks if their references are not in the moved ids', async () => {
const otherBlocks = [
{
id: blockValidIds[1],
attachedBlock: 'some-other-id',
nextBlocks: [],
},
{
id: blockValidIds[2],
attachedBlock: null,
nextBlocks: ['some-other-id-2'],
},
] as Block[];
const mockUpdateOne = jest.spyOn(blockRepository, 'updateOne');
await blockRepository.prepareBlocksOutOfCategoryUpdateScope(otherBlocks, [
blockValidIds[0],
]);
expect(mockUpdateOne).not.toHaveBeenCalled();
});
});
describe('preUpdateMany', () => {
it('should update blocks in and out of the scope', async () => {
const mockFind = jest.spyOn(blockRepository, 'find').mockResolvedValue([
const movedBlocks = [
{ id: validIds[0], category: 'old_category_id' },
{ id: validIds[1], category: 'old_category_id' },
] as Block[];
const otherBlocks = [
{
id: blockValidIds[1],
id: 'other-block-1',
attachedBlock: validIds[0],
nextBlocks: [validIds[0]],
nextBlocks: [],
},
] as Block[]);
] as unknown as Block[];
const prepareBlocksInCategoryUpdateScope = jest.spyOn(
blockRepository,
'prepareBlocksInCategoryUpdateScope',
);
const prepareBlocksOutOfCategoryUpdateScope = jest.spyOn(
blockRepository,
'prepareBlocksOutOfCategoryUpdateScope',
);
const mockFind = jest
.spyOn(blockRepository, 'find')
.mockResolvedValueOnce(movedBlocks)
.mockResolvedValueOnce(otherBlocks);
const prepareBlocksInCategoryUpdateScope = jest
.spyOn(blockRepository, 'prepareBlocksInCategoryUpdateScope')
.mockResolvedValue(undefined);
const prepareBlocksOutOfCategoryUpdateScope = jest
.spyOn(blockRepository, 'prepareBlocksOutOfCategoryUpdateScope')
.mockResolvedValue(undefined);
await blockRepository.preUpdateMany(
{} as any,
@ -274,20 +339,27 @@ describe('BlockRepository', () => {
{ $set: { category: validCategory } },
);
expect(mockFind).toHaveBeenCalled();
const objectIds = validIds.map((id) => new Types.ObjectId(id));
expect(mockFind).toHaveBeenCalledTimes(2);
expect(mockFind).toHaveBeenNthCalledWith(1, {
_id: { $in: validIds },
});
expect(mockFind).toHaveBeenNthCalledWith(2, {
_id: { $nin: objectIds },
category: movedBlocks[0].category,
$or: [
{ attachedBlock: { $in: objectIds } },
{ nextBlocks: { $in: objectIds } },
],
});
expect(prepareBlocksInCategoryUpdateScope).toHaveBeenCalledWith(
validCategory,
[blockValidIds[1]],
validIds,
);
expect(prepareBlocksOutOfCategoryUpdateScope).toHaveBeenCalledWith(
[
{
id: blockValidIds[1],
attachedBlock: validIds[0],
nextBlocks: [validIds[0]],
},
],
[blockValidIds[1]],
otherBlocks,
validIds,
);
});