ユーザーリストの移行は追加のみを行う

This commit is contained in:
tamaina 2023-04-20 18:03:06 +00:00
parent ccfbc89047
commit f27038448c
2 changed files with 38 additions and 11 deletions

View file

@ -5,10 +5,11 @@ import { bindThis } from '@/decorators.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js'; import type { Config } from '@/config.js';
import type { LocalUser } from '@/models/entities/User.js'; import type { LocalUser } from '@/models/entities/User.js';
import type { BlockingsRepository, FollowingsRepository, InstancesRepository, Muting, MutingsRepository, UserListJoiningsRepository, UsersRepository } from '@/models/index.js'; import type { BlockingsRepository, FollowingsRepository, InstancesRepository, MutingsRepository, UserListJoiningsRepository, UsersRepository } from '@/models/index.js';
import type { RelationshipJobData, ThinUser } from '@/queue/types.js'; import type { RelationshipJobData, ThinUser } from '@/queue/types.js';
import type { User } from '@/models/entities/User.js'; import type { User } from '@/models/entities/User.js';
import { IdService } from '@/core/IdService.js';
import { AccountUpdateService } from '@/core/AccountUpdateService.js'; import { AccountUpdateService } from '@/core/AccountUpdateService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js'; import { GlobalEventService } from '@/core/GlobalEventService.js';
import { QueueService } from '@/core/QueueService.js'; import { QueueService } from '@/core/QueueService.js';
@ -49,6 +50,7 @@ export class AccountMoveService {
private instancesRepository: InstancesRepository, private instancesRepository: InstancesRepository,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private idService: IdService,
private apRendererService: ApRendererService, private apRendererService: ApRendererService,
private apDeliverManagerService: ApDeliverManagerService, private apDeliverManagerService: ApDeliverManagerService,
private globalEventService: GlobalEventService, private globalEventService: GlobalEventService,
@ -195,20 +197,45 @@ export class AccountMoveService {
} }
} }
/**
* Update lists while moving accounts.
* - No removal of the old account from the lists
* - Users number limit is not checked
*
* @param src ThinUser (old account)
* @param dst User (new account)
* @returns Promise<void>
*/
@bindThis @bindThis
public async updateLists(src: ThinUser, dst: User): Promise<void> { public async updateLists(src: ThinUser, dst: User): Promise<void> {
// Return if there is no list to be updated. // Return if there is no list to be updated.
const exists = await this.userListJoiningsRepository.exist({ const oldJoinings = await this.userListJoiningsRepository.find({
where: { where: {
userId: src.id, userId: src.id,
}, },
}); });
if (!exists) return; if (oldJoinings.length === 0) return;
await this.userListJoiningsRepository.update( const newJoinings: Map<string, { createdAt: Date; userId: string; userListId: string; }> = new Map();
{ userId: src.id },
{ userId: dst.id } // 重複しないようにIDを生成
); const genId = () => {
let id: string;
do {
id = this.idService.genId();
} while (newJoinings.has(id));
return id;
};
for (const joining of oldJoinings) {
newJoinings.set(genId(), {
createdAt: new Date(),
userId: dst.id,
userListId: joining.userListId,
});
}
const arrayToInsert = Array.from(newJoinings.entries()).map(entry => ({ ...entry[1], id: entry[0] }));
await this.userListJoiningsRepository.insert(arrayToInsert);
// Have the proxy account follow the new account in the same way as UserListService.push // Have the proxy account follow the new account in the same way as UserListService.push
if (this.userEntityService.isRemoteUser(dst)) { if (this.userEntityService.isRemoteUser(dst)) {

View file

@ -45,7 +45,6 @@ describe('Account Move', () => {
Mutings = connection.getRepository(Muting); Mutings = connection.getRepository(Muting);
}, 1000 * 60 * 2); }, 1000 * 60 * 2);
afterAll(async () => { afterAll(async () => {
await app.close(); await app.close();
}); });
@ -206,7 +205,7 @@ describe('Account Move', () => {
const followings = await api('/users/following', { const followings = await api('/users/following', {
userId: carol.id, userId: carol.id,
}, carol) }, carol);
assert.strictEqual(followings.status, 200); assert.strictEqual(followings.status, 200);
assert.strictEqual(followings.body.length, 2); assert.strictEqual(followings.body.length, 2);
assert.strictEqual(followings.body[0].followeeId, bob.id); assert.strictEqual(followings.body[0].followeeId, bob.id);
@ -225,8 +224,9 @@ describe('Account Move', () => {
const lists = await api('/users/lists/list', {}, root); const lists = await api('/users/lists/list', {}, root);
assert.strictEqual(lists.status, 200); assert.strictEqual(lists.status, 200);
assert.strictEqual(lists.body[0].userIds.length, 1); assert.strictEqual(lists.body[0].userIds.length, 2);
assert.strictEqual(lists.body[0].userIds[0], bob.id); assert.ok(lists.body[0].userIds.find((id: string) => id === bob.id));
assert.ok(lists.body[0].userIds.find((id: string) => id === alice.id));
}); });
test('Follow and follower counts are properly adjusted', async () => { test('Follow and follower counts are properly adjusted', async () => {