Skip to content

Commit

Permalink
implement visitor to change ids in links
Browse files Browse the repository at this point in the history
  • Loading branch information
Metauriel committed Dec 8, 2023
1 parent cbd4f87 commit 9a88ef4
Show file tree
Hide file tree
Showing 2 changed files with 190 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { LinkElement } from '@shared/domain/domainobject';
import { EntityId } from '@shared/domain/types';
import {
cardFactory,
columnBoardFactory,
columnFactory,
externalToolElementFactory,
fileElementFactory,
linkElementFactory,
richTextElementFactory,
submissionContainerElementFactory,
submissionItemFactory,
} from '@shared/testing';
import { drawingElementFactory } from '@shared/testing/factory/domainobject/board/drawing-element.do.factory';
import { ObjectId } from 'bson';
import { SwapInternalLinksVisitor } from './swap-internal-links.visitor';

describe('swap internal links visitor', () => {
it('should keep link unchanged', () => {
const map = new Map<EntityId, EntityId>();
const linkElement = linkElementFactory.build({ url: 'testurl.dev' });
const visitor = new SwapInternalLinksVisitor(map);

linkElement.accept(visitor);

expect(linkElement.url).toEqual('testurl.dev');
});

const setupIdPair = () => {
const originalId = new ObjectId().toString();
const newId = new ObjectId().toString();
const value = {
originalId,
newId,
originalUrl: `testurl.dev/${originalId}`,
expectedUrl: `testurl.dev/${newId}`,
};
return value;
};

const buildIdMap = (pairs: { originalId: string; newId: string }[]) => {
const map = new Map<EntityId, EntityId>();
pairs.forEach((pair) => {
map.set(pair.originalId, pair.newId);
});
return map;
};

const buildBoardContaining = (linkelelements: LinkElement[]) => {
const cardContainingLinks = cardFactory.build({ children: linkelelements });
const submissionContainer = submissionContainerElementFactory.build({
children: [
submissionItemFactory.build({
children: [richTextElementFactory.build()],
}),
],
});
const cardContainingOthers = cardFactory.build({
children: [
richTextElementFactory.build(),
fileElementFactory.build(),
submissionContainer,
drawingElementFactory.build(),
externalToolElementFactory.build(),
],
});
const column = columnFactory.build({
children: [cardContainingLinks, cardContainingOthers],
});
const columnBoard = columnBoardFactory.build({
children: [column],
});
return columnBoard;
};

describe('when a single id is matched', () => {
const setupWithIdPair = () => {
const pair = setupIdPair();
const map = buildIdMap([pair]);
const visitor = new SwapInternalLinksVisitor(map);

return { pair, visitor };
};

it('should change ids in link', () => {
const { pair, visitor } = setupWithIdPair();
const linkElement = linkElementFactory.build({ url: pair.originalUrl });

linkElement.accept(visitor);

expect(linkElement.url).toEqual(pair.expectedUrl);
});

it('should change ids in multiple matching links', () => {
const { pair, visitor } = setupWithIdPair();
const firstLinkElement = linkElementFactory.build({ url: pair.originalUrl });
const secondLinkElement = linkElementFactory.build({ url: pair.originalUrl });
const root = buildBoardContaining([firstLinkElement, secondLinkElement]);

root.accept(visitor);

expect(firstLinkElement.url).toEqual(pair.expectedUrl);
expect(secondLinkElement.url).toEqual(pair.expectedUrl);
});
});

describe('when multiple different ids are matched', () => {
const setupWithMultipleIds = () => {
const pairs = [setupIdPair(), setupIdPair()];

const idMap = buildIdMap(pairs);
const visitor = new SwapInternalLinksVisitor(idMap);

return { visitor, pairs };
};

const buildLinkElementsWithUrls = (urls: string[]) => urls.map((url) => linkElementFactory.build({ url }));

it('should change multiple ids in different links', () => {
const { visitor, pairs } = setupWithMultipleIds();
const linkElements = buildLinkElementsWithUrls(pairs.map((pair) => pair.originalUrl));
const root = buildBoardContaining(linkElements);

root.accept(visitor);

expect(linkElements[0].url).toEqual(pairs[0].expectedUrl);
expect(linkElements[1].url).toEqual(pairs[1].expectedUrl);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {
AnyBoardDo,
BoardCompositeVisitor,
Card,
Column,
ColumnBoard,
LinkElement,
SubmissionContainerElement,
SubmissionItem,
} from '@shared/domain/domainobject';
import { DrawingElement } from '@shared/domain/domainobject/board/drawing-element.do';
import { EntityId } from '@shared/domain/types';

export class SwapInternalLinksVisitor implements BoardCompositeVisitor {
constructor(map: Map<EntityId, EntityId>) {
this.idMap = map;
}

private idMap: Map<EntityId, EntityId>;

visitDrawingElement(drawingElement: DrawingElement): void {
this.visitChildrenOf(drawingElement);
}

visitCard(card: Card): void {
this.visitChildrenOf(card);
}

visitColumn(column: Column): void {
this.visitChildrenOf(column);
}

visitColumnBoard(columnBoard: ColumnBoard): void {
this.visitChildrenOf(columnBoard);
}

visitExternalToolElement(): void {}

visitFileElement(): void {}

visitLinkElement(linkElement: LinkElement): void {
this.idMap.forEach((value, key) => {
linkElement.url = linkElement.url.replace(key, value);
});
}

visitRichTextElement(): void {}

visitSubmissionContainerElement(submissionContainerElement: SubmissionContainerElement): void {
this.visitChildrenOf(submissionContainerElement);
}

visitSubmissionItem(submissionItem: SubmissionItem): void {
this.visitChildrenOf(submissionItem);
}

private visitChildrenOf(boardDo: AnyBoardDo) {
boardDo.children.map((child) => child.accept(this));
}
}

0 comments on commit 9a88ef4

Please sign in to comment.