From 01b7ce11bab2becd1b7373bdc443918848d3666a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Acid=20Chicken=20=28=E7=A1=AB=E9=85=B8=E9=B6=8F=29?= Date: Mon, 29 May 2023 04:59:44 +0900 Subject: [PATCH] test: add stories for `MkChannelFollowButton` --- packages/frontend/.storybook/fakes.ts | 46 ++++++++ packages/frontend/.storybook/generate.tsx | 2 +- .../MkChannelFollowButton.stories.impl.ts | 109 ++++++++++++++++++ 3 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 packages/frontend/src/components/MkChannelFollowButton.stories.impl.ts diff --git a/packages/frontend/.storybook/fakes.ts b/packages/frontend/.storybook/fakes.ts index 5fd21cdf0..b9558948a 100644 --- a/packages/frontend/.storybook/fakes.ts +++ b/packages/frontend/.storybook/fakes.ts @@ -17,6 +17,27 @@ export function abuseUserReport() { }; } +export function channel() { + return { + id: 'somechannelid', + createdAt: '2016-12-28T22:49:51.000Z', + lastNotedAt: '2023-01-01T00:00:00.000Z', + name: 'AKANEā˜†CHANNEL', + description: 'sweetie sweet', + userId: 'someuserid', + bannerUrl: 'https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/fedi.jpg?raw=true', + pinnedNoteIds: ['somenoteid'], + color: '#eb613f', + isArchived: false, + usersCount: 16, + notesCount: 1024, + isFollowing: false, + isFavorited: false, + hasUnreadNote: false, + pinnedNotes: [note()], + } +} + export function galleryPost(isSensitive = false) { return { id: 'somepostid', @@ -60,6 +81,31 @@ export function file(isSensitive = false) { }; } +export function note() { + return { + id: 'somenoteid', + createdAt: '2016-12-28T22:49:51.000Z', + userId: 'someuserid', + user: userDetailed(), + text: 'make some noise', + cw: 'sing along', + visibility: 'public', + localOnly: false, + reactionAcceptance: null, + renoteCount: 4, + repliesCount: 2, + reactions: { + 'šŸ‘': 16, + ':yo@.:': 8, + }, + reactionEmojis: {}, + fileIds: [], + files: [], + replyId: null, + renoteId: null, + } +} + export function userDetailed(id = 'someuserid', username = 'miskist', host = 'misskey-hub.net', name = 'Misskey User'): entities.UserDetailed { return { id, diff --git a/packages/frontend/.storybook/generate.tsx b/packages/frontend/.storybook/generate.tsx index f44242210..4a4fbb76c 100644 --- a/packages/frontend/.storybook/generate.tsx +++ b/packages/frontend/.storybook/generate.tsx @@ -396,7 +396,7 @@ function toStories(component: string): string { // glob('src/{components,pages,ui,widgets}/**/*.vue') Promise.all([ glob('src/components/global/*.vue'), - glob('src/components/Mk{A,B}*.vue'), + glob('src/components/Mk{A,B,C}*.vue'), glob('src/components/MkDigitalClock.vue'), glob('src/components/MkGalleryPostPreview.vue'), glob('src/components/MkSignupServerRules.vue'), diff --git a/packages/frontend/src/components/MkChannelFollowButton.stories.impl.ts b/packages/frontend/src/components/MkChannelFollowButton.stories.impl.ts new file mode 100644 index 000000000..1c856b77b --- /dev/null +++ b/packages/frontend/src/components/MkChannelFollowButton.stories.impl.ts @@ -0,0 +1,109 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +import { action } from '@storybook/addon-actions'; +import { userEvent, waitFor, within } from '@storybook/testing-library'; +import { StoryObj } from '@storybook/vue3'; +import { rest } from 'msw'; +import { channel } from '../../.storybook/fakes'; +import { commonHandlers } from '../../.storybook/mocks'; +import MkChannelFollowButton from './MkChannelFollowButton.vue'; +export const Default = { + render(args) { + return { + components: { + MkChannelFollowButton, + }, + setup() { + return { + args, + }; + }, + computed: { + props() { + return { + ...this.args, + }; + }, + events() { + return { + + }; + }, + }, + template: '', + }; + }, + args: { + channel: channel(), + }, + parameters: { + layout: 'centered', + msw: { + handlers: [ + ...commonHandlers, + rest.post('/api/channels/follow', async (req, res, ctx) => { + action('POST /api/channels/follow')(await req.json()); + return res(ctx.status(204)); + }), + rest.post('/api/channels/unfollow', async (req, res, ctx) => { + action('POST /api/channels/unfollow')(await req.json()); + return res(ctx.status(204)); + }), + ], + }, + }, +} satisfies StoryObj; +export const Following = { + ...Default, + async play({ canvasElement }) { + const canvas = within(canvasElement); + const button = canvas.getByRole('button'); + await waitFor(() => userEvent.click(button)); + }, + parameters: { + ...Default.parameters, + msw: { + handlers: [ + ...commonHandlers, + rest.post('/api/channels/follow', async (req, res, ctx) => { + action('POST /api/channels/follow')(await req.json()); + await new Promise(() => {}); + }), + rest.post('/api/channels/unfollow', async (req, res, ctx) => { + action('POST /api/channels/unfollow')(await req.json()); + await new Promise(() => {}); + }), + ], + }, + }, +} +export const Followed = { + ...Default, + args: { + ...Default.args, + channel: { + ...channel(), + isFollowing: true, + }, + }, +} satisfies StoryObj; +export const Full = { + ...Default, + args: { + ...Default.args, + full: true, + }, +} satisfies StoryObj; +export const FullFollowing = { + ...Following, + args: { + ...Following.args, + full: true, + }, +} satisfies StoryObj; +export const FullFollowed = { + ...Followed, + args: { + ...Followed.args, + full: true, + }, +} satisfies StoryObj;