From 190cff47af779418ae160fb7881df4bb1bd24d7a Mon Sep 17 00:00:00 2001 From: KleinChiu <65886108+KleinChiu@users.noreply.github.com> Date: Wed, 22 Jun 2022 08:43:20 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC?= =?UTF-8?q?=E3=81=A8=E3=82=A2=E3=83=90=E3=82=BF=E3=83=BC=E3=81=AE=E9=96=A2?= =?UTF-8?q?=E9=80=A3=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit アバター取得は非同期であるべき、かつ 初期に設定すべき、なので プレイヤーに静的非同期メソッドで初期化する 外部でプレイヤーをインスタンス化する場合はNew関数を使用すること --- core/Account/User.test.ts | 32 ++++++++++++++++++++++++++++++++ core/Account/User.ts | 19 ++++++++++--------- 2 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 core/Account/User.test.ts diff --git a/core/Account/User.test.ts b/core/Account/User.test.ts new file mode 100644 index 0000000..03aa257 --- /dev/null +++ b/core/Account/User.test.ts @@ -0,0 +1,32 @@ +import { IAccountRepository } from "infrastructure"; +import { Avatar, Race } from "./Avatar"; +import { Player, User } from "./User"; + +describe("User's functionality", () => { + test("password hashing", () => { + const cases = [ + { raw: "password", hash: "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8" }, + { raw: "cello", hash: "9bbf02efd82322aadc5d06c9bcf35bb4b0e3302ca158dc800407be1a4fea67e2" }, + ]; + + cases.forEach((c) => { + expect(User.hashPassword(c.raw)).toBe(c.hash.toLowerCase()); + }); + }); +}); + +describe("Player's functionality", () => { + test("player level", () => { + [ + { exp: 0, lv: 0 }, + { exp: 1250, lv: 5 }, + { exp: 5000, lv: 10 }, + ].forEach(async (c) => { + const repoMock = jest.fn(() => new Avatar(Race.Egg, c.exp)); + const p = await Player.New({ getAvatar: repoMock } as unknown as IAccountRepository, "", ""); + const lv = p.level; + expect(repoMock).toBeCalledTimes(1); + expect(lv).toBe(c.lv); + }); + }); +}); diff --git a/core/Account/User.ts b/core/Account/User.ts index 2ef620a..f961fc6 100644 --- a/core/Account/User.ts +++ b/core/Account/User.ts @@ -60,21 +60,22 @@ export class LoginOptions { } export class Player extends User { - private _avatar?: Avatar; - - public get avatar(): Avatar { - return (this._avatar = this._avatar ?? this.repo.getAvatar(this.accountId)); - } - - public set avatar(value: Avatar) { - this._avatar = value; - } + public avatar!: Avatar; public get level(): number { return this.avatar.level; } + /** + * プレイヤーをインスタンス化する場合は`New`を使ってください。 + */ constructor(repo: IAccountRepository, accountId: string, email: string) { super(repo, accountId, email); } + + public static async New(repo: IAccountRepository, accountId: string, email: string): Promise { + const p = new Player(repo, accountId, email); + p.avatar = await p.repo.getAvatar(p.accountId); + return p; + } }