mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-07-26 07:54:53 +02:00
fix(backend): フォロー中のチャンネルを再度フォローした際にALREADY_FOLLOWINGエラーを返すように (#17802)
* test(e2e): フォロー中のチャンネルに再度フォローAPIを叩いた場合のテストを追加 * fix(backend): フォロー中のチャンネルを再度フォローした際にALREADY_FOLLOWINGエラーを返すように * docs(changelog): update changelog
This commit is contained in:
@@ -71,6 +71,7 @@
|
||||
- Fix: フォロワー限定投稿へのリプライをホーム投稿に出来る問題を修正
|
||||
- Fix: ファイルをアップロードするAPIにて、処理終了後に一時ファイルが削除されないことがある問題を修正
|
||||
- Fix: 初期設定で作成したアカウント以外でアカウント作成APIが使用できない問題を修正
|
||||
- Fix: フォロー中のチャンネルを再度フォローした際にALREADY_FOLLOWINGエラーを返すように
|
||||
|
||||
## 2026.6.0
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ import { GlobalEvents, GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { MiLocalUser } from '@/models/User.js';
|
||||
import { RedisKVCache } from '@/misc/cache.js';
|
||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||
import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js';
|
||||
|
||||
@Injectable()
|
||||
export class ChannelFollowingService implements OnModuleInit {
|
||||
@@ -96,11 +98,18 @@ export class ChannelFollowingService implements OnModuleInit {
|
||||
requestUser: MiLocalUser,
|
||||
targetChannel: MiChannel,
|
||||
): Promise<void> {
|
||||
await this.channelFollowingsRepository.insert({
|
||||
id: this.idService.gen(),
|
||||
followerId: requestUser.id,
|
||||
followeeId: targetChannel.id,
|
||||
});
|
||||
try {
|
||||
await this.channelFollowingsRepository.insert({
|
||||
id: this.idService.gen(),
|
||||
followerId: requestUser.id,
|
||||
followeeId: targetChannel.id,
|
||||
});
|
||||
} catch (e) {
|
||||
if (isDuplicateKeyValueError(e)) {
|
||||
throw new IdentifiableError('6e335e39-0203-4418-a936-b3f2dc987845', 'already following');
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
this.globalEventService.publishInternalEvent('followChannel', {
|
||||
userId: requestUser.id,
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { ChannelsRepository } from '@/models/_.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { ChannelFollowingService } from '@/core/ChannelFollowingService.js';
|
||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||
import { ApiError } from '../../error.js';
|
||||
|
||||
export const meta = {
|
||||
@@ -25,6 +26,11 @@ export const meta = {
|
||||
code: 'NO_SUCH_CHANNEL',
|
||||
id: 'c0031718-d573-4e85-928e-10039f1fbb68',
|
||||
},
|
||||
alreadyFollowing: {
|
||||
message: 'You are already following that channel.',
|
||||
code: 'ALREADY_FOLLOWING',
|
||||
id: '7db31665-651e-40c1-8e6e-28e9ad829a2d',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
@@ -52,7 +58,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
throw new ApiError(meta.errors.noSuchChannel);
|
||||
}
|
||||
|
||||
await this.channelFollowingService.follow(me, channel);
|
||||
try {
|
||||
await this.channelFollowingService.follow(me, channel);
|
||||
} catch (e) {
|
||||
if (e instanceof IdentifiableError) {
|
||||
if (e.id === '6e335e39-0203-4418-a936-b3f2dc987845') throw new ApiError(meta.errors.alreadyFollowing);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
36
packages/backend/test/e2e/channel.ts
Normal file
36
packages/backend/test/e2e/channel.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
process.env.NODE_ENV = 'test';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { describe, beforeAll, test } from 'vitest';
|
||||
import { api, castAsError, signup } from '../utils.js';
|
||||
import type * as misskey from 'misskey-js';
|
||||
|
||||
describe('Channel', () => {
|
||||
let alice: misskey.entities.SignupResponse;
|
||||
beforeAll(async () => {
|
||||
alice = await signup({ username: 'alice' });
|
||||
});
|
||||
|
||||
describe('Follow', () => {
|
||||
let channel: misskey.entities.ChannelsCreateResponse;
|
||||
|
||||
beforeAll(async () => {
|
||||
const res = await api('channels/create', { name: 'follow-test-channel' }, alice);
|
||||
channel = res.body;
|
||||
});
|
||||
|
||||
test('フォローしているチャンネルを再度フォローするとALREADY_FOLLOWINGエラーになる', async () => {
|
||||
const res1 = await api('channels/follow', { channelId: channel.id }, alice);
|
||||
assert.strictEqual(res1.status, 204);
|
||||
|
||||
const res2 = await api('channels/follow', { channelId: channel.id }, alice);
|
||||
assert.strictEqual(res2.status, 400);
|
||||
assert.strictEqual(castAsError(res2.body as any).error.code, 'ALREADY_FOLLOWING');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user