feat(profile): системные бейджи рядом с ником
- участники сервера отдают список бейджей из badges_json (AGENT.md 7.2): список расширяемый, назначается только системой - клиент: каталог бейджей (щит администратора инстанса, корона владельца, ранний сторонник, проверенный), неизвестные показываются нейтральной меткой - бейджи видны в ленте, списке участников и друзьях вместо текстовой плашки - тесты: Go (бейджи в списке участников) и Vitest (каталог и отрисовка)
This commit is contained in:
@@ -101,6 +101,7 @@ const authors: AuthorDirectory = {
|
||||
avatarFileId: undefined,
|
||||
colorHex: null,
|
||||
isInstanceAdmin: false,
|
||||
isOwner: false,
|
||||
isMember: true,
|
||||
}),
|
||||
resolveWebhook: () => ({
|
||||
@@ -109,6 +110,7 @@ const authors: AuthorDirectory = {
|
||||
avatarFileId: undefined,
|
||||
colorHex: null,
|
||||
isInstanceAdmin: false,
|
||||
isOwner: false,
|
||||
isMember: false,
|
||||
}),
|
||||
resolveMention: (userId) => ({
|
||||
|
||||
@@ -31,6 +31,7 @@ const authors: AuthorDirectory = {
|
||||
avatarFileId: undefined,
|
||||
colorHex: null,
|
||||
isInstanceAdmin: false,
|
||||
isOwner: false,
|
||||
isMember: true,
|
||||
}),
|
||||
resolveWebhook: () => ({
|
||||
@@ -39,6 +40,7 @@ const authors: AuthorDirectory = {
|
||||
avatarFileId: undefined,
|
||||
colorHex: null,
|
||||
isInstanceAdmin: false,
|
||||
isOwner: false,
|
||||
isMember: false,
|
||||
}),
|
||||
resolveMention: (userId) => ({ name: userId === 'user-2' ? 'Bob' : userId, isMe: false }),
|
||||
|
||||
@@ -72,6 +72,7 @@ const authors: AuthorDirectory = {
|
||||
avatarFileId: undefined,
|
||||
colorHex: null,
|
||||
isInstanceAdmin: false,
|
||||
isOwner: false,
|
||||
isMember: true,
|
||||
}),
|
||||
resolveWebhook: () => ({
|
||||
@@ -80,6 +81,7 @@ const authors: AuthorDirectory = {
|
||||
avatarFileId: undefined,
|
||||
colorHex: null,
|
||||
isInstanceAdmin: false,
|
||||
isOwner: false,
|
||||
isMember: false,
|
||||
}),
|
||||
resolveMention: (userId) => ({ name: userId, isMe: false }),
|
||||
|
||||
@@ -19,6 +19,7 @@ const authors: AuthorDirectory = {
|
||||
avatarFileId: undefined,
|
||||
colorHex: null,
|
||||
isInstanceAdmin: false,
|
||||
isOwner: false,
|
||||
isMember: true,
|
||||
}),
|
||||
resolveWebhook: () => ({
|
||||
@@ -27,6 +28,7 @@ const authors: AuthorDirectory = {
|
||||
avatarFileId: undefined,
|
||||
colorHex: null,
|
||||
isInstanceAdmin: false,
|
||||
isOwner: false,
|
||||
isMember: false,
|
||||
}),
|
||||
resolveMention: (userId) => ({ name: userId === 'user-1' ? 'Аля' : 'Bob', isMe: false }),
|
||||
@@ -223,6 +225,7 @@ describe('сообщения вебхуков', () => {
|
||||
avatarUrl: message.webhook_avatar,
|
||||
colorHex: null,
|
||||
isInstanceAdmin: false,
|
||||
isOwner: false,
|
||||
isMember: false,
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -4,6 +4,7 @@ import userEvent from '@testing-library/user-event';
|
||||
|
||||
import { AnimatedImage } from '@/components/ui/AnimatedImage';
|
||||
import { FramedAvatar, Nickname } from '@/components/profile/Cosmetics';
|
||||
import { SystemBadges } from '@/components/profile/SystemBadges';
|
||||
import { nickColorStyle, nickEffectClass } from '@/components/profile/cosmeticsStyle';
|
||||
import {
|
||||
bodyOf,
|
||||
@@ -498,3 +499,31 @@ describe('фон комнаты', () => {
|
||||
expect(image?.getAttribute('data-animated')).toBe('animated');
|
||||
});
|
||||
});
|
||||
|
||||
describe('системные бейджи', () => {
|
||||
it('показывает щит администратора инстанса и корону владельца', () => {
|
||||
render(<SystemBadges badges={['instance_admin', 'early_supporter']} isOwner isInstanceAdmin />);
|
||||
|
||||
expect(screen.getByTestId('system-badge-instance_admin')).toHaveTextContent('🛡');
|
||||
expect(screen.getByTestId('system-badge-guild_owner')).toHaveTextContent('👑');
|
||||
expect(screen.getByTestId('system-badge-early_supporter')).toHaveAttribute(
|
||||
'title',
|
||||
'Ранний сторонник',
|
||||
);
|
||||
// Администратор инстанса помечен даже без записи в badges_json.
|
||||
expect(screen.getByLabelText('Администратор инстанса')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('неизвестный бейдж показывается нейтральной меткой, а не пропадает', () => {
|
||||
render(<SystemBadges badges={['future_badge']} />);
|
||||
|
||||
const badge = screen.getByTestId('system-badge-future_badge');
|
||||
expect(badge).toHaveTextContent('•');
|
||||
expect(badge).toHaveAttribute('title', 'future_badge');
|
||||
});
|
||||
|
||||
it('без бейджей ничего не рисует', () => {
|
||||
const { container } = render(<SystemBadges />);
|
||||
expect(container.querySelector('[data-testid="system-badges"]')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -29,6 +29,7 @@ const authors: AuthorDirectory = {
|
||||
avatarFileId: undefined,
|
||||
colorHex: null,
|
||||
isInstanceAdmin: false,
|
||||
isOwner: false,
|
||||
isMember: userId === 'user-2',
|
||||
}),
|
||||
resolveWebhook: () => ({
|
||||
@@ -37,6 +38,7 @@ const authors: AuthorDirectory = {
|
||||
avatarFileId: undefined,
|
||||
colorHex: null,
|
||||
isInstanceAdmin: false,
|
||||
isOwner: false,
|
||||
isMember: false,
|
||||
}),
|
||||
resolveMention: (userId) => ({ name: userId === 'user-2' ? 'Боб' : userId, isMe: false }),
|
||||
|
||||
Reference in New Issue
Block a user