diff --git a/CHANGELOG.md b/CHANGELOG.md index 204f7227dc..893258fbe9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ - Fix: フォローリクエストの通知が残る問題を修正 ### Client +- チャンネル検索ですべてのチャンネルの取得/表示ができるように - 通知の表示をカスタマイズできるように - コントロールパネルのカスタム絵文字ページおよびaboutのカスタム絵文字の検索インプットで、`:emojiname1::emojiname2:`のように検索して絵文字を検索できるように * 絵文字ピッカーから入力可能になります @@ -46,6 +47,7 @@ - ドライブのファイル一覧から直接ノートを作成できるように ### Server +- channel/searchのqueryが空の場合に全てのチャンネルを返すように変更 - 環境変数MISSKEY_CONFIG_YMLで設定ファイルをdefault.ymlから変更可能に - Fix: 他のサーバーの情報が取得できないことがある問題を修正 - Fix: エクスポートデータの拡張子がunknownになる問題を修正 diff --git a/packages/backend/src/server/api/endpoints/channels/search.ts b/packages/backend/src/server/api/endpoints/channels/search.ts index a954ba224c..900723ff8a 100644 --- a/packages/backend/src/server/api/endpoints/channels/search.ts +++ b/packages/backend/src/server/api/endpoints/channels/search.ts @@ -48,13 +48,15 @@ export default class extends Endpoint { super(meta, paramDef, async (ps, me) => { const query = this.queryService.makePaginationQuery(this.channelsRepository.createQueryBuilder('channel'), ps.sinceId, ps.untilId); - if (ps.type === 'nameAndDescription') { - query.andWhere(new Brackets(qb => { qb - .where('channel.name ILIKE :q', { q: `%${ sqlLikeEscape(ps.query) }%` }) - .orWhere('channel.description ILIKE :q', { q: `%${ sqlLikeEscape(ps.query) }%` }); - })); - } else { - query.andWhere('channel.name ILIKE :q', { q: `%${ sqlLikeEscape(ps.query) }%` }); + if (ps.query !== '') { + if (ps.type === 'nameAndDescription') { + query.andWhere(new Brackets(qb => { qb + .where('channel.name ILIKE :q', { q: `%${ sqlLikeEscape(ps.query) }%` }) + .orWhere('channel.description ILIKE :q', { q: `%${ sqlLikeEscape(ps.query) }%` }); + })); + } else { + query.andWhere('channel.name ILIKE :q', { q: `%${ sqlLikeEscape(ps.query) }%` }); + } } const channels = await query diff --git a/packages/backend/test/e2e/endpoints.ts b/packages/backend/test/e2e/endpoints.ts index 6898435084..f885209b7f 100644 --- a/packages/backend/test/e2e/endpoints.ts +++ b/packages/backend/test/e2e/endpoints.ts @@ -403,6 +403,100 @@ describe('Endpoints', () => { }); }); + describe('channels/search', () => { + test('空白検索で一覧を取得できる', async () => { + await api('/channels/create', { + name: 'aaa', + description: 'bbb', + }, bob); + await api('/channels/create', { + name: 'ccc1', + description: 'ddd1', + }, bob); + await api('/channels/create', { + name: 'ccc2', + description: 'ddd2', + }, bob); + + const res = await api('/channels/search', { + query: '', + }, bob); + + assert.strictEqual(res.status, 200); + assert.strictEqual(typeof res.body === 'object' && Array.isArray(res.body), true); + assert.strictEqual(res.body.length, 3); + }); + test('名前のみの検索で名前を検索できる', async () => { + const res = await api('/channels/search', { + query: 'aaa', + type: 'nameOnly', + }, bob); + + assert.strictEqual(res.status, 200); + assert.strictEqual(typeof res.body === 'object' && Array.isArray(res.body), true); + assert.strictEqual(res.body.length, 1); + assert.strictEqual(res.body[0].name, 'aaa'); + }); + test('名前のみの検索で名前を複数検索できる', async () => { + const res = await api('/channels/search', { + query: 'ccc', + type: 'nameOnly', + }, bob); + + assert.strictEqual(res.status, 200); + assert.strictEqual(typeof res.body === 'object' && Array.isArray(res.body), true); + assert.strictEqual(res.body.length, 2); + }); + test('名前のみの検索で説明は検索できない', async () => { + const res = await api('/channels/search', { + query: 'bbb', + type: 'nameOnly', + }, bob); + + assert.strictEqual(res.status, 200); + assert.strictEqual(typeof res.body === 'object' && Array.isArray(res.body), true); + assert.strictEqual(res.body.length, 0); + }); + test('名前と説明の検索で名前を検索できる', async () => { + const res = await api('/channels/search', { + query: 'ccc1', + }, bob); + + assert.strictEqual(res.status, 200); + assert.strictEqual(typeof res.body === 'object' && Array.isArray(res.body), true); + assert.strictEqual(res.body.length, 1); + assert.strictEqual(res.body[0].name, 'ccc1'); + }); + test('名前と説明での検索で説明を検索できる', async () => { + const res = await api('/channels/search', { + query: 'ddd1', + }, bob); + + assert.strictEqual(res.status, 200); + assert.strictEqual(typeof res.body === 'object' && Array.isArray(res.body), true); + assert.strictEqual(res.body.length, 1); + assert.strictEqual(res.body[0].name, 'ccc1'); + }); + test('名前と説明の検索で名前を複数検索できる', async () => { + const res = await api('/channels/search', { + query: 'ccc', + }, bob); + + assert.strictEqual(res.status, 200); + assert.strictEqual(typeof res.body === 'object' && Array.isArray(res.body), true); + assert.strictEqual(res.body.length, 2); + }); + test('名前と説明での検索で説明を複数検索できる', async () => { + const res = await api('/channels/search', { + query: 'ddd', + }, bob); + + assert.strictEqual(res.status, 200); + assert.strictEqual(typeof res.body === 'object' && Array.isArray(res.body), true); + assert.strictEqual(res.body.length, 2); + }); + }); + describe('drive', () => { test('ドライブ情報を取得できる', async () => { await uploadFile(alice, { diff --git a/packages/frontend/src/pages/channels.vue b/packages/frontend/src/pages/channels.vue index 70e7705d1d..e670cdd864 100644 --- a/packages/frontend/src/pages/channels.vue +++ b/packages/frontend/src/pages/channels.vue @@ -96,7 +96,7 @@ const ownedPagination = { async function search() { const query = searchQuery.toString().trim(); - if (query == null || query === '') return; + if (query == null) return; const type = searchType.toString().trim();