diff options
author | crupest <crupest@outlook.com> | 2020-10-27 18:52:01 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2020-10-27 18:52:01 +0800 |
commit | 14e5848c23c643cea9b5d709770747d98c3d75e2 (patch) | |
tree | e82df858c37d1917c13d8edbe8a4f95245be5710 | |
parent | 03eebbf710bfc7148493cc5a598e6cc096ee0632 (diff) | |
download | timeline-14e5848c23c643cea9b5d709770747d98c3d75e2.tar.gz timeline-14e5848c23c643cea9b5d709770747d98c3d75e2.tar.bz2 timeline-14e5848c23c643cea9b5d709770747d98c3d75e2.zip |
refactor: Remove mock backend.
-rw-r--r-- | Timeline/ClientApp/package.json | 3 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/http/mock/common.ts | 78 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/http/mock/default-avatar.png | bin | 26442 -> 0 bytes | |||
-rw-r--r-- | Timeline/ClientApp/src/app/http/mock/install.ts | 11 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/http/mock/timeline.ts | 660 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/http/mock/token.ts | 53 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/http/mock/user.ts | 139 | ||||
-rw-r--r-- | Timeline/ClientApp/webpack.config.dev.js | 10 |
8 files changed, 1 insertions, 953 deletions
diff --git a/Timeline/ClientApp/package.json b/Timeline/ClientApp/package.json index 84b5b7d5..65c5cbe2 100644 --- a/Timeline/ClientApp/package.json +++ b/Timeline/ClientApp/package.json @@ -37,7 +37,6 @@ },
"scripts": {
"start": "webpack-dev-server --config ./webpack.config.dev.js",
- "start:mock": "webpack-dev-server --config ./webpack.config.dev.js --env.TIMELINE_USE_MOCK_BACKEND",
"build": "webpack --config ./webpack.config.prod.js",
"lint": "eslint src/ --ext .js --ext .jsx --ext .ts --ext .tsx"
},
@@ -65,7 +64,6 @@ "@babel/preset-typescript": "^7.12.1",
"@hot-loader/react-dom": "^17.0.0",
"@types/classnames": "^2.2.10",
- "@types/crypto-js": "^4.0.1",
"@types/lodash": "^4.14.162",
"@types/node": "^14.14.5",
"@types/react": "^16.9.53",
@@ -83,7 +81,6 @@ "babel-plugin-transform-builtin-extend": "^1.1.2",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^6.2.1",
- "crypto-js": "^4.0.0",
"css-loader": "^5.0.0",
"eslint": "^7.12.1",
"eslint-config-prettier": "^6.14.0",
diff --git a/Timeline/ClientApp/src/app/http/mock/common.ts b/Timeline/ClientApp/src/app/http/mock/common.ts deleted file mode 100644 index 787d81bd..00000000 --- a/Timeline/ClientApp/src/app/http/mock/common.ts +++ /dev/null @@ -1,78 +0,0 @@ -import localforage from "localforage"; -import { SHA1 } from "crypto-js"; - -import { HttpNetworkError } from "../common"; - -export const mockStorage = localforage.createInstance({ - name: "mock-backend", - description: "Database for mock back end.", - driver: localforage.INDEXEDDB, -}); - -export async function sha1(data: Blob): Promise<string> { - const s = await new Promise<string>((resolve) => { - const fileReader = new FileReader(); - fileReader.readAsBinaryString(data); - fileReader.onload = () => { - resolve(fileReader.result as string); - }; - }); - - return SHA1(s).toString(); -} - -const disableNetworkKey = "mockServer.disableNetwork"; -const networkLatencyKey = "mockServer.networkLatency"; - -let disableNetwork: boolean = - localStorage.getItem(disableNetworkKey) === "true" ? true : false; - -const savedNetworkLatency = localStorage.getItem(networkLatencyKey); - -let networkLatency: number | null = - savedNetworkLatency != null ? Number(savedNetworkLatency) : null; - -Object.defineProperty(window, "disableNetwork", { - get: () => disableNetwork, - set: (value) => { - if (value) { - disableNetwork = true; - localStorage.setItem(disableNetworkKey, "true"); - } else { - disableNetwork = false; - localStorage.setItem(disableNetworkKey, "false"); - } - }, -}); - -Object.defineProperty(window, "networkLatency", { - get: () => networkLatency, - set: (value) => { - if (typeof value === "number") { - networkLatency = value; - localStorage.setItem(networkLatencyKey, value.toString()); - } else if (value == null) { - networkLatency = null; - localStorage.removeItem(networkLatencyKey); - } - }, -}); - -export async function mockPrepare(key: string): Promise<void> { - console.log(`Recieve request: ${key}`); - - if (disableNetwork) { - console.warn("Network is disabled for mock server."); - throw new HttpNetworkError(); - } - if (networkLatency != null) { - await new Promise((resolve) => { - window.setTimeout(() => { - resolve(); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - }, networkLatency! * 1000); - }); - } - - await Promise.resolve(); -} diff --git a/Timeline/ClientApp/src/app/http/mock/default-avatar.png b/Timeline/ClientApp/src/app/http/mock/default-avatar.png Binary files differdeleted file mode 100644 index 4086e1d2..00000000 --- a/Timeline/ClientApp/src/app/http/mock/default-avatar.png +++ /dev/null diff --git a/Timeline/ClientApp/src/app/http/mock/install.ts b/Timeline/ClientApp/src/app/http/mock/install.ts deleted file mode 100644 index 17b7cc13..00000000 --- a/Timeline/ClientApp/src/app/http/mock/install.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { setHttpTokenClient } from "../token"; -import { setHttpUserClient } from "../user"; -import { setHttpTimelineClient } from "../timeline"; - -import { MockHttpTokenClient } from "./token"; -import { MockHttpUserClient } from "./user"; -import { MockHttpTimelineClient } from "./timeline"; - -setHttpTokenClient(new MockHttpTokenClient()); -setHttpUserClient(new MockHttpUserClient()); -setHttpTimelineClient(new MockHttpTimelineClient()); diff --git a/Timeline/ClientApp/src/app/http/mock/timeline.ts b/Timeline/ClientApp/src/app/http/mock/timeline.ts deleted file mode 100644 index 27addd61..00000000 --- a/Timeline/ClientApp/src/app/http/mock/timeline.ts +++ /dev/null @@ -1,660 +0,0 @@ -import { random, without, range } from "lodash"; - -import { BlobWithEtag, NotModified } from "../common"; -import { - IHttpTimelineClient, - HttpTimelineInfo, - TimelineVisibility, - HttpTimelineListQuery, - HttpTimelineNotExistError, - HttpTimelinePostRequest, - HttpTimelineNameConflictError, - HttpTimelinePatchRequest, - HttpTimelinePostInfo, - HttpTimelinePostContent, - HttpTimelinePostPostRequest, - HttpTimelinePostNotExistError, - HttpTimelineGenericPostInfo, -} from "../timeline"; -import { HttpUser } from "../user"; - -import { mockStorage, sha1, mockPrepare } from "./common"; -import { getUser, MockUserNotExistError, checkToken } from "./user"; - -async function getTimelineNameList(): Promise<string[]> { - return (await mockStorage.getItem<string[]>("timelines")) ?? []; -} - -async function setTimelineNameList(newOne: string[]): Promise<void> { - await mockStorage.setItem<string[]>("timelines", newOne); -} - -type TimelinePropertyKey = - | "uniqueId" - | "lastModified" - | "owner" - | "description" - | "visibility" - | "members" - | "currentPostId"; - -function getTimelinePropertyKey( - name: string, - property: TimelinePropertyKey -): string { - return `timeline.${name}.${property}`; -} - -function getTimelinePropertyValue<T>( - name: string, - property: TimelinePropertyKey -): Promise<T> { - return mockStorage.getItem<T>( - getTimelinePropertyKey(name, property) - ) as Promise<T>; -} - -function setTimelinePropertyValue<T>( - name: string, - property: TimelinePropertyKey, - value: T -): Promise<void> { - return mockStorage - .setItem<T>(getTimelinePropertyKey(name, property), value) - .then(); -} - -function updateTimelineLastModified(name: string): Promise<void> { - return setTimelinePropertyValue( - name, - "lastModified", - new Date().toISOString() - ); -} - -interface HttpTimelineInfoEx extends HttpTimelineInfo { - memberUsernames: string[]; -} - -function createUniqueId(): string { - const s = "abcdefghijklmnopqrstuvwxz0123456789"; - let result = ""; - for (let i = 0; i < 16; i++) { - result += s[random(0, s.length - 1)]; - } - return result; -} - -class MockTimelineNotExistError extends Error { - constructor() { - super("Timeline not exist."); - } -} - -class MockTimelineAlreadyExistError extends Error { - constructor() { - super("Timeline already exist."); - } -} - -async function getTimelineInfo(name: string): Promise<HttpTimelineInfoEx> { - let owner: HttpUser; - if (name.startsWith("@")) { - const ownerUsername = name.substr(1); - owner = await getUser(ownerUsername); - const optionalUniqueId = await getTimelinePropertyValue<string | null>( - name, - "uniqueId" - ); - if (optionalUniqueId == null) { - await setTimelineNameList([...(await getTimelineNameList()), name]); - await setTimelinePropertyValue(name, "uniqueId", createUniqueId()); - await updateTimelineLastModified(name); - } - } else { - const optionalOwnerUsername = await getTimelinePropertyValue<string | null>( - name, - "owner" - ); - if (optionalOwnerUsername == null) { - throw new MockTimelineNotExistError(); - } else { - owner = await getUser(optionalOwnerUsername); - } - } - - const memberUsernames = - (await getTimelinePropertyValue<string[] | null>(name, "members")) ?? []; - const members = await Promise.all( - memberUsernames.map(async (username) => { - return await getUser(username); - }) - ); - - return { - name, - uniqueId: await getTimelinePropertyValue<string>(name, "uniqueId"), - owner, - description: - (await getTimelinePropertyValue<string | null>(name, "description")) ?? - "", - visibility: - (await getTimelinePropertyValue<TimelineVisibility | null>( - name, - "visibility" - )) ?? "Register", - lastModified: new Date( - await getTimelinePropertyValue<string>(name, "lastModified") - ), - members, - memberUsernames, - }; -} - -async function createTimeline(name: string, owner: string): Promise<void> { - const optionalOwnerUsername = await getTimelinePropertyValue<string | null>( - name, - "owner" - ); - if (optionalOwnerUsername != null) { - throw new MockTimelineAlreadyExistError(); - } - - await setTimelineNameList([...(await getTimelineNameList()), name]); - await setTimelinePropertyValue(name, "uniqueId", createUniqueId()); - await setTimelinePropertyValue(name, "owner", owner); - await updateTimelineLastModified(name); -} - -type TimelinePostPropertyKey = - | "type" - | "data" - | "etag" - | "author" - | "time" - | "lastUpdated"; - -function getTimelinePostPropertyKey( - timelineName: string, - id: number, - propertyKey: TimelinePostPropertyKey -): string { - return `timeline.${timelineName}.posts.${id}.${propertyKey}`; -} - -function getTimelinePostPropertyValue<T>( - timelineName: string, - id: number, - propertyKey: TimelinePostPropertyKey -): Promise<T> { - return mockStorage.getItem<T>( - getTimelinePostPropertyKey(timelineName, id, propertyKey) - ) as Promise<T>; -} - -function setTimelinePostPropertyValue<T>( - timelineName: string, - id: number, - propertyKey: TimelinePostPropertyKey, - value: T -): Promise<T> { - return mockStorage.setItem( - getTimelinePostPropertyKey(timelineName, id, propertyKey), - value - ); -} - -function removeTimelinePostProperty( - timelineName: string, - id: number, - propertyKey: TimelinePostPropertyKey -): Promise<void> { - return mockStorage.removeItem( - getTimelinePostPropertyKey(timelineName, id, propertyKey) - ); -} - -async function getTimelinePostInfo( - timelineName: string, - id: number -): Promise<HttpTimelineGenericPostInfo> { - const currentPostId = await getTimelinePropertyValue<number | null>( - timelineName, - "currentPostId" - ); - if (currentPostId == null || id > currentPostId) { - throw new HttpTimelinePostNotExistError(); - } - - const type = await getTimelinePostPropertyValue<string | null>( - timelineName, - id, - "type" - ); - - if (type == null) { - return { - id, - author: await getUser( - await getTimelinePostPropertyValue<string>(timelineName, id, "author") - ), - time: new Date( - await getTimelinePostPropertyValue<string>(timelineName, id, "time") - ), - lastUpdated: new Date( - await getTimelinePostPropertyValue<string>( - timelineName, - id, - "lastUpdated" - ) - ), - deleted: true, - }; - } else { - let content: HttpTimelinePostContent; - if (type === "text") { - content = { - type: "text", - text: await getTimelinePostPropertyValue(timelineName, id, "data"), - }; - } else { - content = { - type: "image", - }; - } - - return { - id, - author: await getUser( - await getTimelinePostPropertyValue<string>(timelineName, id, "author") - ), - time: new Date( - await getTimelinePostPropertyValue<string>(timelineName, id, "time") - ), - lastUpdated: new Date( - await getTimelinePostPropertyValue<string>( - timelineName, - id, - "lastUpdated" - ) - ), - content, - deleted: false, - }; - } -} - -export class MockHttpTimelineClient implements IHttpTimelineClient { - async listTimeline( - query: HttpTimelineListQuery - ): Promise<HttpTimelineInfo[]> { - await mockPrepare("timeline.list"); - return ( - await Promise.all( - (await getTimelineNameList()).map((name) => getTimelineInfo(name)) - ) - ).filter((timeline) => { - if ( - query.visibility != null && - query.visibility !== timeline.visibility - ) { - return false; - } - if (query.relate != null) { - if (query.relateType === "own") { - if (timeline.owner.username !== query.relate) { - return false; - } - } else if (query.relateType === "join") { - if (!timeline.memberUsernames.includes(query.relate)) { - return false; - } - } else if ( - timeline.owner.username !== query.relate && - !timeline.memberUsernames.includes(query.relate) - ) { - return false; - } - } - return true; - }); - } - - getTimeline(timelineName: string): Promise<HttpTimelineInfo>; - getTimeline( - timelineName: string, - query: { - checkUniqueId?: string; - } - ): Promise<HttpTimelineInfo>; - getTimeline( - timelineName: string, - query: { - checkUniqueId?: string; - ifModifiedSince: Date; - } - ): Promise<HttpTimelineInfo | NotModified>; - async getTimeline( - timelineName: string, - query?: { - checkUniqueId?: string; - ifModifiedSince?: Date; - } - ): Promise<HttpTimelineInfo | NotModified> { - await mockPrepare("timeline.get"); - try { - const timeline = await getTimelineInfo(timelineName); - if (query != null && query.ifModifiedSince != null) { - if (timeline.lastModified >= query.ifModifiedSince) { - return timeline; - } else { - if ( - query.checkUniqueId != null && - timeline.uniqueId != query.checkUniqueId - ) { - return timeline; - } else { - return new NotModified(); - } - } - } - - return timeline; - } catch (e) { - if ( - e instanceof MockTimelineNotExistError || - e instanceof MockUserNotExistError - ) { - throw new HttpTimelineNotExistError(); - } - throw e; - } - } - - async postTimeline( - req: HttpTimelinePostRequest, - token: string - ): Promise<HttpTimelineInfo> { - await mockPrepare("timeline.post"); - const user = checkToken(token); - try { - await createTimeline(req.name, user); - } catch (e) { - if (e instanceof MockTimelineAlreadyExistError) { - throw new HttpTimelineNameConflictError(); - } - throw e; - } - return await getTimelineInfo(req.name); - } - - async patchTimeline( - timelineName: string, - req: HttpTimelinePatchRequest, - _token: string - ): Promise<HttpTimelineInfo> { - await mockPrepare("timeline.patch"); - let modified = false; - if (req.description != null) { - modified = true; - await setTimelinePropertyValue( - timelineName, - "description", - req.description - ); - } - if (req.visibility != null) { - modified = true; - await setTimelinePropertyValue( - timelineName, - "visibility", - req.visibility - ); - } - if (modified) { - await updateTimelineLastModified(timelineName); - } - return await getTimelineInfo(timelineName); - } - - async deleteTimeline(timelineName: string, _token: string): Promise<void> { - await mockPrepare("timeline.delete"); - await setTimelineNameList( - without(await getTimelineNameList(), timelineName) - ); - await mockStorage.removeItem( - getTimelinePropertyKey(timelineName, "uniqueId") - ); - - // TODO: remove other things - } - - async memberPut( - timelineName: string, - username: string, - _token: string - ): Promise<void> { - await mockPrepare("timeline.member.put"); - const oldMembers = - (await getTimelinePropertyValue<string[] | null>( - timelineName, - "members" - )) ?? []; - if (!oldMembers.includes(username)) { - await setTimelinePropertyValue(timelineName, "members", [ - ...oldMembers, - username, - ]); - await updateTimelineLastModified(timelineName); - } - } - - async memberDelete( - timelineName: string, - username: string, - _token: string - ): Promise<void> { - await mockPrepare("timeline.member.delete"); - const oldMembers = - (await getTimelinePropertyValue<string[] | null>( - timelineName, - "members" - )) ?? []; - if (oldMembers.includes(username)) { - await setTimelinePropertyValue( - timelineName, - "members", - without(oldMembers, username) - ); - await updateTimelineLastModified(timelineName); - } - } - - listPost( - timelineName: string, - token?: string - ): Promise<HttpTimelinePostInfo[]>; - listPost( - timelineName: string, - token: string | undefined, - query: { - modifiedSince?: Date; - includeDeleted?: false; - } - ): Promise<HttpTimelinePostInfo[]>; - listPost( - timelineName: string, - token: string | undefined, - query: { - modifiedSince?: Date; - includeDeleted: true; - } - ): Promise<HttpTimelineGenericPostInfo[]>; - async listPost( - timelineName: string, - _token?: string, - query?: { - modifiedSince?: Date; - includeDeleted?: boolean; - } - ): Promise<HttpTimelineGenericPostInfo[]> { - await mockPrepare("timeline.post.list"); - // TODO: Permission check. - - const currentPostId = await getTimelinePropertyValue<number | null>( - timelineName, - "currentPostId" - ); - - return ( - await Promise.all( - range(1, currentPostId == null ? 1 : currentPostId + 1).map( - async (id) => { - return await getTimelinePostInfo(timelineName, id); - } - ) - ) - ) - .filter((post) => { - if (query?.includeDeleted !== true && post.deleted) { - return false; - } - return true; - }) - .filter((post) => { - if (query?.modifiedSince != null) { - return post.lastUpdated >= query.modifiedSince; - } - return true; - }); - } - - getPostData( - timelineName: string, - postId: number, - token: string - ): Promise<BlobWithEtag>; - async getPostData( - timelineName: string, - postId: number, - _token?: string, - etag?: string - ): Promise<BlobWithEtag | NotModified> { - await mockPrepare("timeline.post.data.get"); - // TODO: Permission check. - - const optionalSavedEtag = await getTimelinePostPropertyValue<string>( - timelineName, - postId, - "etag" - ); - - if (optionalSavedEtag == null) { - const optionalType = await getTimelinePostPropertyValue<string>( - timelineName, - postId, - "type" - ); - - if (optionalType != null) { - throw new Error("Post of this type has no data."); - } else { - throw new HttpTimelinePostNotExistError(); - } - } - - if (etag === optionalSavedEtag) { - return new NotModified(); - } - - return { - data: await getTimelinePostPropertyValue<Blob>( - timelineName, - postId, - "data" - ), - etag: optionalSavedEtag, - }; - } - - async postPost( - timelineName: string, - req: HttpTimelinePostPostRequest, - token: string - ): Promise<HttpTimelinePostInfo> { - await mockPrepare("timeline.post.post"); - const user = checkToken(token); - - const savedId = await getTimelinePropertyValue<number | null>( - timelineName, - "currentPostId" - ); - const id = savedId ? savedId + 1 : 1; - await setTimelinePropertyValue(timelineName, "currentPostId", id); - - await setTimelinePostPropertyValue(timelineName, id, "author", user); - - const currentTimeString = new Date().toISOString(); - await setTimelinePostPropertyValue( - timelineName, - id, - "lastUpdated", - currentTimeString - ); - - await setTimelinePostPropertyValue( - timelineName, - id, - "time", - req.time != null ? req.time.toISOString() : currentTimeString - ); - - const { content } = req; - if (content.type === "text") { - await setTimelinePostPropertyValue(timelineName, id, "type", "text"); - await setTimelinePostPropertyValue( - timelineName, - id, - "data", - content.text - ); - } else { - await setTimelinePostPropertyValue(timelineName, id, "type", "image"); - await setTimelinePostPropertyValue( - timelineName, - id, - "data", - content.data - ); - await setTimelinePostPropertyValue( - timelineName, - id, - "etag", - await sha1(content.data) - ); - } - - return (await getTimelinePostInfo( - timelineName, - id - )) as HttpTimelinePostInfo; - } - - async deletePost( - timelineName: string, - postId: number, - _token: string - ): Promise<void> { - await mockPrepare("timeline.post.delete"); - // TODO: permission check - await removeTimelinePostProperty(timelineName, postId, "type"); - await removeTimelinePostProperty(timelineName, postId, "data"); - await removeTimelinePostProperty(timelineName, postId, "etag"); - await setTimelinePostPropertyValue( - timelineName, - postId, - "lastUpdated", - new Date().toISOString() - ); - } -} diff --git a/Timeline/ClientApp/src/app/http/mock/token.ts b/Timeline/ClientApp/src/app/http/mock/token.ts deleted file mode 100644 index 0a350894..00000000 --- a/Timeline/ClientApp/src/app/http/mock/token.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { AxiosError } from "axios"; - -import { - IHttpTokenClient, - HttpCreateTokenRequest, - HttpCreateTokenResponse, - HttpVerifyTokenRequest, - HttpVerifyTokenResponse, -} from "../token"; - -import { mockPrepare } from "./common"; -import { getUser, MockUserNotExistError, checkToken } from "./user"; - -export class MockHttpTokenClient implements IHttpTokenClient { - // TODO: Mock bad credentials error. - async create(req: HttpCreateTokenRequest): Promise<HttpCreateTokenResponse> { - await mockPrepare("token.create"); - try { - const user = await getUser(req.username); - return { - user, - token: `token-${req.username}`, - }; - } catch (e) { - if (e instanceof MockUserNotExistError) { - throw { - isAxiosError: true, - response: { - status: 400, - }, - } as Partial<AxiosError>; - } - throw e; - } - } - - async verify(req: HttpVerifyTokenRequest): Promise<HttpVerifyTokenResponse> { - await mockPrepare("token.verify"); - try { - const user = await getUser(checkToken(req.token)); - return { - user, - }; - } catch (e) { - throw { - isAxiosError: true, - response: { - status: 400, - }, - } as Partial<AxiosError>; - } - } -} diff --git a/Timeline/ClientApp/src/app/http/mock/user.ts b/Timeline/ClientApp/src/app/http/mock/user.ts deleted file mode 100644 index 7948da11..00000000 --- a/Timeline/ClientApp/src/app/http/mock/user.ts +++ /dev/null @@ -1,139 +0,0 @@ -import axios from "axios"; - -import { BlobWithEtag, NotModified } from "../common"; -import { - IHttpUserClient, - HttpUser, - HttpUserNotExistError, - HttpUserPatchRequest, - HttpChangePasswordRequest, -} from "../user"; - -import { mockStorage, sha1, mockPrepare } from "./common"; -import defaultAvatarUrl from "./default-avatar.png"; - -let _defaultAvatar: BlobWithEtag | undefined = undefined; - -async function getDefaultAvatar(): Promise<BlobWithEtag> { - if (_defaultAvatar == null) { - const blob = ( - await axios.get<Blob>(defaultAvatarUrl, { - responseType: "blob", - }) - ).data; - const etag = await sha1(blob); - _defaultAvatar = { - data: blob, - etag, - }; - } - return _defaultAvatar; -} - -export class MockTokenError extends Error { - constructor() { - super("Token bad format."); - } -} - -export class MockUserNotExistError extends Error { - constructor() { - super('Only two user "user" and "admin".'); - } -} - -export function checkUsername( - username: string -): asserts username is "user" | "admin" { - if (!["user", "admin"].includes(username)) throw new MockUserNotExistError(); -} - -export function checkToken(token: string): string { - if (!token.startsWith("token-")) { - throw new MockTokenError(); - } - return token.substr(6); -} - -const uniqueIdMap = { - user: "e4c80127d092d9b2fc19c5e04612d4c0", - admin: "5640fa45435f9a55077b9f77c42a77bb", -}; - -export async function getUser( - username: "user" | "admin" | string -): Promise<HttpUser> { - checkUsername(username); - const savedNickname = await mockStorage.getItem<string>( - `user.${username}.nickname` - ); - return { - uniqueId: uniqueIdMap[username], - username: username, - nickname: - savedNickname == null || savedNickname === "" ? username : savedNickname, - administrator: username === "admin", - }; -} - -export class MockHttpUserClient implements IHttpUserClient { - async get(username: string): Promise<HttpUser> { - await mockPrepare("user.get"); - return await getUser(username).catch((e) => { - if (e instanceof MockUserNotExistError) { - throw new HttpUserNotExistError(); - } else { - throw e; - } - }); - } - - async patch( - username: string, - req: HttpUserPatchRequest, - _token: string - ): Promise<HttpUser> { - await mockPrepare("user.patch"); - if (req.nickname != null) { - await mockStorage.setItem(`user.${username}.nickname`, req.nickname); - } - return await getUser(username); - } - - getAvatar(username: string): Promise<BlobWithEtag>; - async getAvatar( - username: string, - etag?: string - ): Promise<BlobWithEtag | NotModified> { - await mockPrepare("user.avatar.get"); - - const savedEtag = await mockStorage.getItem(`user.${username}.avatar.etag`); - if (savedEtag == null) { - return await getDefaultAvatar(); - } - - if (savedEtag === etag) { - return new NotModified(); - } - - return { - data: await mockStorage.getItem<Blob>(`user.${username}.avatar.data`), - etag: await mockStorage.getItem<string>(`user.${username}.avatar.etag`), - }; - } - - async putAvatar(username: string, data: Blob, _token: string): Promise<void> { - await mockPrepare("user.avatar.put"); - const etag = await sha1(data); - await mockStorage.setItem<Blob>(`user.${username}.avatar.data`, data); - await mockStorage.setItem<string>(`user.${username}.avatar.etag`, etag); - } - - async changePassword( - _req: HttpChangePasswordRequest, - _token: string - ): Promise<void> { - await mockPrepare("userop.changepassowrd"); - throw new Error("Not Implemented."); - } -} diff --git a/Timeline/ClientApp/webpack.config.dev.js b/Timeline/ClientApp/webpack.config.dev.js index fea5a2c5..c88e1aaf 100644 --- a/Timeline/ClientApp/webpack.config.dev.js +++ b/Timeline/ClientApp/webpack.config.dev.js @@ -49,12 +49,4 @@ config.devServer config.plugin("hot").use(webpack.HotModuleReplacementPlugin);
-module.exports = (env) => {
- if (env && env.TIMELINE_USE_MOCK_BACKEND) {
- config
- .entry("index")
- .add(path.join(__dirname, "src/app/http/mock/install.ts"));
- }
-
- return config.toConfig();
-};
+module.exports = config.toConfig();
|