Skip to content

Commit

Permalink
fix: add dependency injected objects (for test)
Browse files Browse the repository at this point in the history
  • Loading branch information
laminne committed Jul 24, 2024
1 parent e53c91c commit 609dfba
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 134 deletions.
51 changes: 51 additions & 0 deletions pkg/intermodule/account.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
import { Result } from '@mikuroxina/mini-fn';
import { Cat, Ether } from '@mikuroxina/mini-fn';
import {
InMemoryAccountRepository,
newFollowRepo,
} from '../accounts/adaptor/repository/dummy.js';
import {
PrismaAccountRepository,
prismaFollowRepo,
} from '../accounts/adaptor/repository/prisma.js';
import type {
Account,
AccountID,
AccountName,
} from '../accounts/model/account.js';
import { accountRepoSymbol } from '../accounts/model/repository.js';
import type { FetchService } from '../accounts/service/fetch.js';
import { fetch } from '../accounts/service/fetch.js';
import type { FetchFollowService } from '../accounts/service/fetchFollow.js';
import { fetchFollow } from '../accounts/service/fetchFollow.js';
import { prismaClient } from '../adaptors/prisma.js';

export type { Account } from '../accounts/model/account.js';

Expand Down Expand Up @@ -84,3 +97,41 @@ export class AccountModuleFacade {
);
}
}

const isProduction = process.env.NODE_ENV === 'production';
const accountRepoObject = isProduction
? new PrismaAccountRepository(prismaClient)

Check warning on line 103 in pkg/intermodule/account.ts

View check run for this annotation

Codecov / codecov/patch

pkg/intermodule/account.ts#L103

Added line #L103 was not covered by tests
: new InMemoryAccountRepository([]);
const accountRepository = Ether.newEther(
accountRepoSymbol,
() => accountRepoObject,
);

const accountFollowRepository = isProduction
? prismaFollowRepo(prismaClient)

Check warning on line 111 in pkg/intermodule/account.ts

View check run for this annotation

Codecov / codecov/patch

pkg/intermodule/account.ts#L111

Added line #L111 was not covered by tests
: newFollowRepo();

export const accountModule = new AccountModuleFacade(
Ether.runEther(Cat.cat(fetch).feed(Ether.compose(accountRepository)).value),
Ether.runEther(
Cat.cat(fetchFollow)
.feed(Ether.compose(accountFollowRepository))
.feed(Ether.compose(accountRepository)).value,
),
);

const inMemoryAccountRepository = Ether.newEther(
accountRepoSymbol,
() => new InMemoryAccountRepository([]),
);
const inMemoryFollowRepository = newFollowRepo();
export const dummyAccountModuleFacade = new AccountModuleFacade(
Ether.runEther(
Cat.cat(fetch).feed(Ether.compose(inMemoryAccountRepository)).value,
),
Ether.runEther(
Cat.cat(fetchFollow)
.feed(Ether.compose(inMemoryFollowRepository))
.feed(Ether.compose(inMemoryAccountRepository)).value,
),
);
35 changes: 1 addition & 34 deletions pkg/notes/mod.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
import { OpenAPIHono } from '@hono/zod-openapi';
import { Cat, Ether, Promise, Result } from '@mikuroxina/mini-fn';

import {
InMemoryAccountRepository,
newFollowRepo,
} from '../accounts/adaptor/repository/dummy.js';
import {
PrismaAccountRepository,
prismaFollowRepo,
} from '../accounts/adaptor/repository/prisma.js';
import type { AccountID } from '../accounts/model/account.js';
import { accountRepoSymbol } from '../accounts/model/repository.js';
import { authenticateToken } from '../accounts/service/authenticationTokenService.js';
import { fetch } from '../accounts/service/fetch.js';
import { fetchFollow } from '../accounts/service/fetchFollow.js';
import {
type AuthMiddlewareVariable,
authenticateMiddleware,
} from '../adaptors/authenticateMiddleware.js';
import { prismaClient } from '../adaptors/prisma.js';
import { SnowflakeIDGenerator } from '../id/mod.js';
import type { ID } from '../id/type.js';
import { AccountModuleFacade } from '../intermodule/account.js';
import { accountModule } from '../intermodule/account.js';

Check warning on line 13 in pkg/notes/mod.ts

View check run for this annotation

Codecov / codecov/patch

pkg/notes/mod.ts#L13

Added line #L13 was not covered by tests
import { BookmarkController } from './adaptor/controller/bookmark.js';
import { NoteController } from './adaptor/controller/note.js';
import {
Expand Down Expand Up @@ -78,28 +67,6 @@ const AuthMiddleware = await Ether.runEtherT(
).value,
);

// Account
const accountRepoObject = isProduction
? new PrismaAccountRepository(prismaClient)
: new InMemoryAccountRepository([]);
const accountRepository = Ether.newEther(
accountRepoSymbol,
() => accountRepoObject,
);

const accountFollowRepository = isProduction
? prismaFollowRepo(prismaClient)
: newFollowRepo();

const accountModule = new AccountModuleFacade(
Ether.runEther(Cat.cat(fetch).feed(Ether.compose(accountRepository)).value),
Ether.runEther(
Cat.cat(fetchFollow)
.feed(Ether.compose(accountFollowRepository))
.feed(Ether.compose(accountRepository)).value,
),
);

// Note
const createService = new CreateService(
noteRepository,
Expand Down
32 changes: 13 additions & 19 deletions pkg/notes/service/fetch.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import { Option, Result } from '@mikuroxina/mini-fn';
import { afterEach, describe, expect, it, vi } from 'vitest';

import {
InMemoryAccountFollowRepository,
InMemoryAccountRepository,
} from '../../accounts/adaptor/repository/dummy.js';
import { InMemoryAccountRepository } from '../../accounts/adaptor/repository/dummy.js';
import { Account, type AccountID } from '../../accounts/model/account.js';
import { FetchService as AccountFetchService } from '../../accounts/service/fetch.js';
import { FetchFollowService } from '../../accounts/service/fetchFollow.js';
import { AccountModuleFacade } from '../../intermodule/account.js';
import { dummyAccountModuleFacade } from '../../intermodule/account.js';
import { InMemoryNoteRepository } from '../adaptor/repository/dummy.js';
import { Note, type NoteID } from '../model/note.js';
import { FetchService } from './fetch.js';
Expand Down Expand Up @@ -90,20 +85,17 @@ const accountRepository = new InMemoryAccountRepository([
testAccount,
frozenAccount,
]);
const accountFollowRepository = new InMemoryAccountFollowRepository();
const accountModule = new AccountModuleFacade(
new AccountFetchService(accountRepository),
new FetchFollowService(accountFollowRepository, accountRepository),
);
const service = new FetchService(repository, accountModule);
const service = new FetchService(repository, dummyAccountModuleFacade);

describe('FetchService', () => {
afterEach(() => accountRepository.reset());

it('should fetch notes', async () => {
vi.spyOn(accountModule, 'fetchAccount').mockImplementation(async () => {
return Result.ok(testAccount);
});
vi.spyOn(dummyAccountModuleFacade, 'fetchAccount').mockImplementation(
async () => {
return Result.ok(testAccount);
},
);
const res = await service.fetchNoteByID('1' as NoteID);

expect(Option.isSome(res)).toBe(true);
Expand All @@ -123,9 +115,11 @@ describe('FetchService', () => {
});

it('account frozen', async () => {
vi.spyOn(accountModule, 'fetchAccount').mockImplementation(async () => {
return Result.ok(frozenAccount);
});
vi.spyOn(dummyAccountModuleFacade, 'fetchAccount').mockImplementation(
async () => {
return Result.ok(frozenAccount);
},

Check warning on line 121 in pkg/notes/service/fetch.test.ts

View check run for this annotation

Codecov / codecov/patch

pkg/notes/service/fetch.test.ts#L120-L121

Added lines #L120 - L121 were not covered by tests
);
const res = await service.fetchNoteByID(frozenUserNote.getID());

expect(Option.isNone(res)).toBe(true);
Expand Down
14 changes: 1 addition & 13 deletions pkg/timeline/mod.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import { OpenAPIHono } from '@hono/zod-openapi';
import { Option, Result } from '@mikuroxina/mini-fn';

import {
InMemoryAccountFollowRepository,
InMemoryAccountRepository,
} from '../accounts/adaptor/repository/dummy.js';
import type { AccountID } from '../accounts/model/account.js';
import { FetchService as AccountFetchService } from '../accounts/service/fetch.js';
import { FetchFollowService } from '../accounts/service/fetchFollow.js';
import { SnowflakeIDGenerator } from '../id/mod.js';
import { AccountModuleFacade } from '../intermodule/account.js';
import { accountModule } from '../intermodule/account.js';

Check warning on line 6 in pkg/timeline/mod.ts

View check run for this annotation

Codecov / codecov/patch

pkg/timeline/mod.ts#L6

Added line #L6 was not covered by tests
import { Note, type NoteID } from '../notes/model/note.js';
import { TimelineController } from './adaptor/controller/timeline.js';
import {
Expand All @@ -33,12 +27,6 @@ const idGenerator = new SnowflakeIDGenerator(0, {
now: () => BigInt(Date.now()),
});

const accountRepository = new InMemoryAccountRepository([]);
const accountFollowRepository = new InMemoryAccountFollowRepository();
const accountModule = new AccountModuleFacade(
new AccountFetchService(accountRepository),
new FetchFollowService(accountFollowRepository, accountRepository),
);
const timelineRepository = new InMemoryTimelineRepository();
const listRepository = new InMemoryListRepository();
const timelineNotesCacheRepository = new InMemoryTimelineCacheRepository();
Expand Down
32 changes: 13 additions & 19 deletions pkg/timeline/service/account.test.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,18 @@
import { Option, Result } from '@mikuroxina/mini-fn';
import { describe, expect, it, vi } from 'vitest';

import {
InMemoryAccountFollowRepository,
InMemoryAccountRepository,
} from '../../accounts/adaptor/repository/dummy.js';
import { Account, type AccountID } from '../../accounts/model/account.js';
import { FetchService as AccountFetchService } from '../../accounts/service/fetch.js';
import { FetchFollowService } from '../../accounts/service/fetchFollow.js';
import { AccountModuleFacade } from '../../intermodule/account.js';
import { dummyAccountModuleFacade } from '../../intermodule/account.js';
import type { PartialAccount } from '../../intermodule/account.js';
import { Note, type NoteID } from '../../notes/model/note.js';
import { InMemoryTimelineRepository } from '../adaptor/repository/dummy.js';
import { AccountTimelineService } from './account.js';
import { NoteVisibilityService } from './noteVisibility.js';

describe('AccountTimelineService', () => {
const accountRepository = new InMemoryAccountRepository([]);
const accountFollowRepository = new InMemoryAccountFollowRepository();
const accountModule = new AccountModuleFacade(
new AccountFetchService(accountRepository),
new FetchFollowService(accountFollowRepository, accountRepository),
const noteVisibilityService = new NoteVisibilityService(
dummyAccountModuleFacade,
);
const noteVisibilityService = new NoteVisibilityService(accountModule);

const dummyPublicNote = Note.new({
id: '1' as NoteID,
Expand Down Expand Up @@ -100,9 +90,11 @@ describe('AccountTimelineService', () => {
});

it('if following', async () => {
vi.spyOn(accountModule, 'fetchFollowers').mockImplementation(async () => {
return Result.ok([partialAccount1]);
});
vi.spyOn(dummyAccountModuleFacade, 'fetchFollowers').mockImplementation(
async () => {
return Result.ok([partialAccount1]);
},
);
const res = await accountTimelineService.handle('100' as AccountID, {
id: '101' as AccountID,
hasAttachment: false,
Expand All @@ -118,9 +110,11 @@ describe('AccountTimelineService', () => {
});

it('if not following', async () => {
vi.spyOn(accountModule, 'fetchFollowers').mockImplementation(async () => {
return Result.ok([partialAccount1]);
});
vi.spyOn(dummyAccountModuleFacade, 'fetchFollowers').mockImplementation(
async () => {
return Result.ok([partialAccount1]);
},
);
const res = await accountTimelineService.handle('100' as AccountID, {
id: '0' as AccountID,
hasAttachment: false,
Expand Down
60 changes: 29 additions & 31 deletions pkg/timeline/service/noteVisibility.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import { Result } from '@mikuroxina/mini-fn';
import { describe, expect, it, vi } from 'vitest';

import {
InMemoryAccountFollowRepository,
InMemoryAccountRepository,
} from '../../accounts/adaptor/repository/dummy.js';
import type { AccountID } from '../../accounts/model/account.js';
import { FetchService as AccountFetchService } from '../../accounts/service/fetch.js';
import { FetchFollowService } from '../../accounts/service/fetchFollow.js';
import { AccountModuleFacade } from '../../intermodule/account.js';
import { dummyAccountModuleFacade } from '../../intermodule/account.js';
import {
dummyDirectNote,
dummyFollowersNote,
Expand All @@ -19,18 +13,14 @@ import {
import { NoteVisibilityService } from './noteVisibility.js';

describe('NoteVisibilityService', () => {
const accountRepository = new InMemoryAccountRepository([]);
const accountFollowRepository = new InMemoryAccountFollowRepository();
const accountModule = new AccountModuleFacade(
new AccountFetchService(accountRepository),
new FetchFollowService(accountFollowRepository, accountRepository),
);
const visibilityService = new NoteVisibilityService(accountModule);
const visibilityService = new NoteVisibilityService(dummyAccountModuleFacade);

it("when author's note: return true", async () => {
vi.spyOn(accountModule, 'fetchFollowers').mockImplementation(async () => {
return Result.ok([partialAccount1]);
});
vi.spyOn(dummyAccountModuleFacade, 'fetchFollowers').mockImplementation(
async () => {
return Result.ok([partialAccount1]);
},

Check warning on line 22 in pkg/timeline/service/noteVisibility.test.ts

View check run for this annotation

Codecov / codecov/patch

pkg/timeline/service/noteVisibility.test.ts#L21-L22

Added lines #L21 - L22 were not covered by tests
);

const testObjects = [
dummyPublicNote,
Expand All @@ -49,9 +39,11 @@ describe('NoteVisibilityService', () => {
});

it('when direct note: return true if sendTo is accountID', async () => {
vi.spyOn(accountModule, 'fetchFollowers').mockImplementation(async () => {
return Result.ok([partialAccount1]);
});
vi.spyOn(dummyAccountModuleFacade, 'fetchFollowers').mockImplementation(
async () => {
return Result.ok([partialAccount1]);
},

Check warning on line 45 in pkg/timeline/service/noteVisibility.test.ts

View check run for this annotation

Codecov / codecov/patch

pkg/timeline/service/noteVisibility.test.ts#L44-L45

Added lines #L44 - L45 were not covered by tests
);

const res = await visibilityService.handle({
accountID: '101' as AccountID,
Expand All @@ -67,9 +59,11 @@ describe('NoteVisibilityService', () => {
});

it('when following: return true if public,home,followers', async () => {
vi.spyOn(accountModule, 'fetchFollowers').mockImplementation(async () => {
return Result.ok([partialAccount1]);
});
vi.spyOn(dummyAccountModuleFacade, 'fetchFollowers').mockImplementation(
async () => {
return Result.ok([partialAccount1]);
},
);
// public
expect(
await visibilityService.handle({
Expand All @@ -94,9 +88,11 @@ describe('NoteVisibilityService', () => {
});

it('when not following: return true if public, home', async () => {
vi.spyOn(accountModule, 'fetchFollowers').mockImplementation(async () => {
return Result.ok([partialAccount1]);
});
vi.spyOn(dummyAccountModuleFacade, 'fetchFollowers').mockImplementation(
async () => {
return Result.ok([partialAccount1]);
},
);

expect(
await visibilityService.handle({
Expand All @@ -120,9 +116,11 @@ describe('NoteVisibilityService', () => {
});

it('always return true if public', async () => {
vi.spyOn(accountModule, 'fetchFollowers').mockImplementation(async () => {
return Result.ok([partialAccount1]);
});
vi.spyOn(dummyAccountModuleFacade, 'fetchFollowers').mockImplementation(
async () => {
return Result.ok([partialAccount1]);
},

Check warning on line 122 in pkg/timeline/service/noteVisibility.test.ts

View check run for this annotation

Codecov / codecov/patch

pkg/timeline/service/noteVisibility.test.ts#L121-L122

Added lines #L121 - L122 were not covered by tests
);

const res = await visibilityService.handle({
accountID: '0' as AccountID,
Expand All @@ -132,8 +130,8 @@ describe('NoteVisibilityService', () => {
});

it("homeTimelineVisibilityCheck: return true if visibility is not 'DIRECT'", async () => {
vi.spyOn(accountModule, 'fetchFollowers').mockImplementation(async () =>
Result.ok([partialAccount1]),
vi.spyOn(dummyAccountModuleFacade, 'fetchFollowers').mockImplementation(
async () => Result.ok([partialAccount1]),
);

expect(
Expand Down
Loading

0 comments on commit 609dfba

Please sign in to comment.