팬덤 탈퇴 · 성운 창립자 권한 승계 · 대표 팬덤 자동 지정
This commit is contained in:
@@ -129,25 +129,62 @@ describe('가입 · 탈퇴 · 대표 팬덤', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('창립자 탈퇴 · 대표 팬덤 자동 지정(Q-PN-03 · Q-PN-04 권고안)', () => {
|
||||
describe('창립자 탈퇴 승계 · 대표 팬덤 자동 지정(원장 C-100 · C-101 · S20)', () => {
|
||||
const setPolicy = (patch: Record<string, unknown>) => db().doc('config/policy').set(patch, { merge: true });
|
||||
const THIRD = 'test-planet-create-third';
|
||||
afterEach(async () => {
|
||||
await db().doc('config/policy').set({
|
||||
nebulaFounderLeaveBlocked: FieldValue.delete(), primaryOnLeave: FieldValue.delete(),
|
||||
}, { merge: true });
|
||||
await db().doc('config/policy').set({ primaryOnLeave: FieldValue.delete() }, { merge: true });
|
||||
await wipeUser(THIRD);
|
||||
await db().recursiveDelete(db().collection(`users/${THIRD}/memberships`));
|
||||
await db().recursiveDelete(db().collection(`users/${OTHER}/notifications`));
|
||||
await db().recursiveDelete(db().collection(`users/${THIRD}/notifications`));
|
||||
});
|
||||
|
||||
it('성운 창립자는 탄생 전 탈퇴 E-FDM-05 · 탄생 뒤에는 탈퇴 가능 · 설정을 끄면 막지 않는다', async () => {
|
||||
const id = (await call(fnNebulaCreate, { name: 'Founder Stay' })).fandomId as string;
|
||||
expect(await codeOf(() => call(fnFandomLeave, { fandomId: id }))).toBe('E-FDM-05');
|
||||
expect((await fandom(id)).memberCount).toBe(1);
|
||||
it('탄생 전 창립자 탈퇴 허용 → 가장 먼저 가입한 남은 멤버가 탄생 권한자 · 알림 · 이전 창립자 탄생 거부 · 순번 비재사용', async () => {
|
||||
const id = (await call(fnNebulaCreate, { name: 'Founder Go' })).fandomId as string;
|
||||
await call(fnFandomJoin, { fandomId: id }, OTHER);
|
||||
await call(fnFandomJoin, { fandomId: id }, THIRD);
|
||||
// 가입 시각을 OTHER < THIRD 로 못박는다.
|
||||
await db().doc(`fandoms/${id}/members/${OTHER}`).update({ joinedAt: Timestamp.fromMillis(Date.now() - 2 * 86_400_000) });
|
||||
await db().doc(`fandoms/${id}/members/${THIRD}`).update({ joinedAt: Timestamp.fromMillis(Date.now() - 86_400_000) });
|
||||
|
||||
const out = await call(fnFandomLeave, { fandomId: id });
|
||||
expect(out).toMatchObject({ left: true, founderUid: OTHER });
|
||||
expect(await fandom(id)).toMatchObject({ founderUid: OTHER, memberCount: 2, memberSeq: 3 });
|
||||
const notes = await db().collection(`users/${OTHER}/notifications`).get();
|
||||
expect(notes.docs.map((d) => d.get('title'))).toEqual(['「Founder Go」 성운의 행성 탄생 권한을 이어받았어요.']);
|
||||
|
||||
await db().doc(`fandoms/${id}`).update({ memberCount: 10, growthPop: 1_000 });
|
||||
const pick = { fandomId: id, planetType: 'shape1', colorKey: 'blue' };
|
||||
expect(await codeOf(() => call(fnPlanetCreate, pick))).toBe('E-PERM-01');
|
||||
|
||||
// 떠난 창립자가 다시 가입해도 #001 이 아니라 다음 순번(#4)을 받는다.
|
||||
await call(fnFandomJoin, { fandomId: id });
|
||||
expect((await db().doc(`fandoms/${id}/members/${UID}`).get()).get('memberNo')).toBe(4);
|
||||
expect((await fandom(id)).founderUid).toBe(OTHER);
|
||||
await call(fnPlanetCreate, pick, OTHER);
|
||||
expect((await fandom(id)).stage).toBe(1);
|
||||
});
|
||||
|
||||
it('창립자 혼자인 성운 — 탈퇴 허용 · 성운 유지 · 탄생 권한은 비웠다가 다음 가입자에게(S20)', async () => {
|
||||
const id = (await call(fnNebulaCreate, { name: 'Founder Alone' })).fandomId as string;
|
||||
expect(await call(fnFandomLeave, { fandomId: id })).toMatchObject({ left: true, founderUid: null });
|
||||
expect(await fandom(id)).toMatchObject({ stage: 0, memberCount: 0, founderUid: null, name: 'Founder Alone' });
|
||||
|
||||
await call(fnFandomJoin, { fandomId: id }, OTHER);
|
||||
expect((await fandom(id)).founderUid).toBe(OTHER);
|
||||
// 이미 권한자가 있으면 다음 가입자는 이어받지 않는다.
|
||||
await call(fnFandomJoin, { fandomId: id }, THIRD);
|
||||
expect((await fandom(id)).founderUid).toBe(OTHER);
|
||||
});
|
||||
|
||||
it('탄생 뒤 창립자 탈퇴는 탄생 권한을 건드리지 않는다', async () => {
|
||||
const id = (await call(fnNebulaCreate, { name: 'Founder Born' })).fandomId as string;
|
||||
await call(fnFandomJoin, { fandomId: id }, OTHER);
|
||||
await db().doc(`fandoms/${id}`).update({ stage: 1 });
|
||||
expect((await call(fnFandomLeave, { fandomId: id })).left).toBe(true);
|
||||
|
||||
const other = (await call(fnNebulaCreate, { name: 'Founder Go' }, OTHER)).fandomId as string;
|
||||
await setPolicy({ nebulaFounderLeaveBlocked: false });
|
||||
expect((await call(fnFandomLeave, { fandomId: other }, OTHER)).left).toBe(true);
|
||||
expect(await call(fnFandomLeave, { fandomId: id })).not.toHaveProperty('founderUid');
|
||||
expect((await fandom(id)).founderUid).toBe(UID);
|
||||
expect((await db().collection(`users/${OTHER}/notifications`).get()).empty).toBe(true);
|
||||
});
|
||||
|
||||
/** A(대표) · B · C 에 가입 — 가입 시각은 B < C 로 못박는다. */
|
||||
|
||||
Reference in New Issue
Block a user