mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-21 17:26:29 -05:00
DIRTY: Mock Repository
Signed-off-by: Yannick Bungers <git@innay.de>
This commit is contained in:
parent
2250495d4f
commit
9263d4468a
2 changed files with 324 additions and 18 deletions
|
@ -9,7 +9,13 @@ import { Test, TestingModule } from '@nestjs/testing';
|
|||
import { getDataSourceToken, getRepositoryToken } from '@nestjs/typeorm';
|
||||
import assert from 'assert';
|
||||
import { Mock } from 'ts-mockery';
|
||||
import { DataSource, EntityManager, Repository } from 'typeorm';
|
||||
import {
|
||||
DataSource,
|
||||
EntityManager,
|
||||
EntityTarget,
|
||||
Repository,
|
||||
SelectQueryBuilder,
|
||||
} from 'typeorm';
|
||||
|
||||
import { AuthToken } from '../auth/auth-token.entity';
|
||||
import { Author } from '../authors/author.entity';
|
||||
|
@ -38,6 +44,8 @@ import { HistoryEntryImportDto } from './history-entry-import.dto';
|
|||
import { HistoryEntry } from './history-entry.entity';
|
||||
import { HistoryService } from './history.service';
|
||||
|
||||
import Any = jasmine.Any;
|
||||
|
||||
describe('HistoryService', () => {
|
||||
let service: HistoryService;
|
||||
let historyRepo: Repository<HistoryEntry>;
|
||||
|
@ -47,16 +55,17 @@ describe('HistoryService', () => {
|
|||
[(entityManager: EntityManager) => Promise<void>]
|
||||
>;
|
||||
|
||||
class CreateQueryBuilderClass {
|
||||
leftJoinAndSelect: () => CreateQueryBuilderClass;
|
||||
where: () => CreateQueryBuilderClass;
|
||||
orWhere: () => CreateQueryBuilderClass;
|
||||
setParameter: () => CreateQueryBuilderClass;
|
||||
getOne: () => HistoryEntry;
|
||||
getMany: () => HistoryEntry[];
|
||||
class CreateQueryBuilderClass<Entity> {
|
||||
leftJoinAndSelect: () => CreateQueryBuilderClass<Entity>;
|
||||
where: () => CreateQueryBuilderClass<Entity>;
|
||||
orWhere: () => CreateQueryBuilderClass<Entity>;
|
||||
setParameter: () => CreateQueryBuilderClass<Entity>;
|
||||
getOne: () => Entity;
|
||||
getMany: () => Entity[];
|
||||
}
|
||||
|
||||
let createQueryBuilderFunc: CreateQueryBuilderClass;
|
||||
let createQueryBuilderFunc: CreateQueryBuilderClass<HistoryEntry>;
|
||||
let createQueryBuilderFuncNote: CreateQueryBuilderClass<Note>;
|
||||
|
||||
beforeEach(async () => {
|
||||
noteRepo = new Repository<Note>(
|
||||
|
@ -148,12 +157,29 @@ describe('HistoryService', () => {
|
|||
getOne: () => historyEntry,
|
||||
getMany: () => [historyEntry],
|
||||
};
|
||||
createQueryBuilderFunc = createQueryBuilder as CreateQueryBuilderClass;
|
||||
createQueryBuilderFunc =
|
||||
createQueryBuilder as CreateQueryBuilderClass<HistoryEntry>;
|
||||
const note = Note.create(null);
|
||||
jest
|
||||
.spyOn(historyRepo, 'createQueryBuilder')
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
.mockImplementation(() => createQueryBuilder);
|
||||
const createQueryBuilderNote = {
|
||||
leftJoinAndSelect: () => createQueryBuilderNote,
|
||||
where: () => createQueryBuilderNote,
|
||||
orWhere: () => createQueryBuilderNote,
|
||||
setParameter: () => createQueryBuilderNote,
|
||||
getOne: () => note,
|
||||
getMany: () => [note],
|
||||
};
|
||||
createQueryBuilderFuncNote =
|
||||
createQueryBuilderNote as CreateQueryBuilderClass<Note>;
|
||||
jest
|
||||
.spyOn(historyRepo, 'createQueryBuilder')
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
.mockImplementation(() => createQueryBuilderNote);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
|
@ -388,16 +414,41 @@ describe('HistoryService', () => {
|
|||
updatedAt: historyEntryImport.lastVisitedAt,
|
||||
};
|
||||
|
||||
const createQueryBuilder = mockSelectQueryBuilderInRepo(noteRepo, note);
|
||||
function createQueryBuilder(entityClass: any): SelectQueryBuilder<any> {
|
||||
if (entityClass.name == 'HistoryEntry') {
|
||||
return mockSelectQueryBuilderInRepo(
|
||||
historyRepo,
|
||||
newlyCreatedHistoryEntry,
|
||||
);
|
||||
} else {
|
||||
return mockSelectQueryBuilderInRepo(noteRepo, note);
|
||||
}
|
||||
}
|
||||
/*
|
||||
class QueryBuilderExtension<Entity> extends SelectQueryBuilder<Entity>{
|
||||
createQueryBuilder(): this {
|
||||
if (Entity.toString() == 'HistoryEntry') {
|
||||
return mockSelectQueryBuilderInRepo(
|
||||
historyRepo,
|
||||
newlyCreatedHistoryEntry,
|
||||
);
|
||||
} else {
|
||||
return mockSelectQueryBuilderInRepo(noteRepo, note);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
const mockedManager = Mock.of<EntityManager>({
|
||||
find: jest.fn().mockResolvedValueOnce([historyEntry]),
|
||||
createQueryBuilder: () => createQueryBuilder,
|
||||
remove: jest.fn().mockImplementationOnce(async (_: HistoryEntry) => {
|
||||
// TODO: reimplement checks below
|
||||
//expect(await (await entry.note).aliases).toHaveLength(1);
|
||||
//expect((await (await entry.note).aliases)[0].name).toEqual(alias);
|
||||
//expect(entry.pinStatus).toEqual(false);
|
||||
remove: jest
|
||||
.fn()
|
||||
.mockImplementationOnce(async (entry: HistoryEntry) => {
|
||||
expect(await (await entry.note).aliases).toHaveLength(1);
|
||||
expect((await (await entry.note).aliases)[0].name).toEqual(alias);
|
||||
expect(entry.pinStatus).toEqual(true);
|
||||
}),
|
||||
createQueryBuilder: jest.fn(),
|
||||
save: jest.fn().mockImplementationOnce(async (entry: HistoryEntry) => {
|
||||
expect((await entry.note).aliases).toEqual(
|
||||
(await newlyCreatedHistoryEntry.note).aliases,
|
||||
|
@ -406,6 +457,11 @@ describe('HistoryService', () => {
|
|||
expect(entry.updatedAt).toEqual(newlyCreatedHistoryEntry.updatedAt);
|
||||
}),
|
||||
});
|
||||
jest
|
||||
.spyOn(mockedManager, 'createQueryBuilder')
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
.mockImplementation((type) => createQueryBuilder(type));
|
||||
mockedTransaction.mockImplementation((cb) => cb(mockedManager));
|
||||
await service.setHistory(user, [historyEntryImport]);
|
||||
});
|
||||
|
|
250
backend/src/utils/test-utils/mockRepository.ts
Normal file
250
backend/src/utils/test-utils/mockRepository.ts
Normal file
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
/*
|
||||
import {
|
||||
DeepPartial,
|
||||
DeleteResult,
|
||||
EntityManager,
|
||||
EntityTarget,
|
||||
FindManyOptions,
|
||||
FindOptionsWhere,
|
||||
InsertResult,
|
||||
ObjectID,
|
||||
QueryRunner,
|
||||
RemoveOptions,
|
||||
Repository,
|
||||
SaveOptions,
|
||||
SelectQueryBuilder,
|
||||
UpdateResult,
|
||||
} from 'typeorm';
|
||||
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
|
||||
import { UpsertOptions } from 'typeorm/repository/UpsertOptions';
|
||||
|
||||
class MockRepository<T> implements Repository<T> {
|
||||
|
||||
entities: T[]
|
||||
|
||||
createQueryBuilder(
|
||||
alias?: string,
|
||||
queryRunner?: QueryRunner,
|
||||
): SelectQueryBuilder<T> {
|
||||
new SelectQueryBuilder()
|
||||
//return super.createQueryBuilder(alias, queryRunner);
|
||||
}
|
||||
find(options?: FindManyOptions<T>): Promise<T[]> {
|
||||
//return super.find(options);
|
||||
}
|
||||
|
||||
clear(): Promise<void> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
count(options: FindManyOptions<T> | undefined): Promise<number> {
|
||||
return Promise.resolve(0);
|
||||
}
|
||||
|
||||
countBy(where: FindOptionsWhere<T> | FindOptionsWhere<T>[]): Promise<number> {
|
||||
return Promise.resolve(0);
|
||||
}
|
||||
|
||||
create(): T {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
decrement(
|
||||
conditions: FindOptionsWhere<T>,
|
||||
propertyPath: string,
|
||||
value: number | string,
|
||||
): Promise<UpdateResult> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
delete(
|
||||
criteria:
|
||||
| string
|
||||
| string[]
|
||||
| number
|
||||
| number[]
|
||||
| Date
|
||||
| Date[]
|
||||
| ObjectID
|
||||
| ObjectID[]
|
||||
| FindOptionsWhere<T>,
|
||||
): Promise<DeleteResult> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
extend<CustomRepository>(
|
||||
custom: CustomRepository & ThisType<Repository<T> & CustomRepository>,
|
||||
): Repository<T> & CustomRepository {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
findAndCount(
|
||||
options: FindManyOptions<T> | undefined,
|
||||
): Promise<[T[], number]> {
|
||||
return Promise.resolve([[], 0]);
|
||||
}
|
||||
|
||||
findAndCountBy(
|
||||
where: FindOptionsWhere<T> | FindOptionsWhere<T>[],
|
||||
): Promise<[T[], number]> {
|
||||
return Promise.resolve([[], 0]);
|
||||
}
|
||||
|
||||
findBy(where: FindOptionsWhere<T> | FindOptionsWhere<T>[]): Promise<T[]> {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
findByIds(ids: any[]): Promise<T[]> {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
findOne(options: FindOneOptions<T>): Promise<T | null> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
findOneBy(
|
||||
where: FindOptionsWhere<T> | FindOptionsWhere<T>[],
|
||||
): Promise<T | null> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
findOneById(id: number | string | Date | ObjectID): Promise<T | null> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
findOneByOrFail(
|
||||
where: FindOptionsWhere<T> | FindOptionsWhere<T>[],
|
||||
): Promise<T> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
findOneOrFail(options: FindOneOptions<T>): Promise<T> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
getId(entity: T): any {}
|
||||
|
||||
hasId(entity: T): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
increment(
|
||||
conditions: FindOptionsWhere<T>,
|
||||
propertyPath: string,
|
||||
value: number | string,
|
||||
): Promise<UpdateResult> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
insert(
|
||||
entity: QueryDeepPartialEntity<T> | QueryDeepPartialEntity<T>[],
|
||||
): Promise<InsertResult> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
readonly manager: EntityManager;
|
||||
|
||||
merge(mergeIntoEntity: T, entityLikes: DeepPartial<T>): T {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
get metadata(): import('..').EntityMetadata {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
preload(entityLike: DeepPartial<T>): Promise<T | undefined> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
query(query: string, parameters: any[] | undefined): Promise<any> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
readonly queryRunner: QueryRunner;
|
||||
|
||||
recover<T>(
|
||||
entities: T[],
|
||||
options: SaveOptions & { reload: false },
|
||||
): Promise<T[]> {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
remove(entities: T[], options: RemoveOptions | undefined): Promise<T[]> {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
restore(
|
||||
criteria:
|
||||
| string
|
||||
| string[]
|
||||
| number
|
||||
| number[]
|
||||
| Date
|
||||
| Date[]
|
||||
| ObjectID
|
||||
| ObjectID[]
|
||||
| FindOptionsWhere<T>,
|
||||
): Promise<UpdateResult> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
save<T>(
|
||||
entities: T[],
|
||||
options: SaveOptions & { reload: false },
|
||||
): Promise<T[]> {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
softDelete(
|
||||
criteria:
|
||||
| string
|
||||
| string[]
|
||||
| number
|
||||
| number[]
|
||||
| Date
|
||||
| Date[]
|
||||
| ObjectID
|
||||
| ObjectID[]
|
||||
| FindOptionsWhere<T>,
|
||||
): Promise<UpdateResult> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
softRemove<T>(
|
||||
entities: T[],
|
||||
options: SaveOptions & { reload: false },
|
||||
): Promise<T[]> {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
readonly target: EntityTarget<T>;
|
||||
|
||||
update(
|
||||
criteria:
|
||||
| string
|
||||
| string[]
|
||||
| number
|
||||
| number[]
|
||||
| Date
|
||||
| Date[]
|
||||
| ObjectID
|
||||
| ObjectID[]
|
||||
| FindOptionsWhere<T>,
|
||||
partialEntity: QueryDeepPartialEntity<T>,
|
||||
): Promise<UpdateResult> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
upsert(
|
||||
entityOrEntities: QueryDeepPartialEntity<T> | QueryDeepPartialEntity<T>[],
|
||||
conflictPathsOrOptions: string[] | UpsertOptions<T>,
|
||||
): Promise<InsertResult> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
}
|
||||
*/
|
Loading…
Reference in a new issue