XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEServerManager

【Java】我的世界XFE服务器管理器

公开
关注 0 Fork 0 Star 0
UTF-8
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { describe, expect, it, vi } from 'vitest';
import { App } from '../app';
import { ServerProvider } from '../context/server-context';
import { ApiClient } from '../lib/api';
import { I18nProvider } from '../lib/i18n';

describe('player action confirmation', () => {
  it('uses the server-issued preview token for the second-stage mutation', async () => {
    localStorage.setItem('xfesm.locale', 'en-US');
    location.hash = '/players';
    const client = new ApiClient();
    vi.spyOn(client, 'session').mockResolvedValue({
      authenticated: true,
      csrfToken: 'csrf',
      actor: { id: 'owner-id', displayName: 'owner', roles: ['owner'], permissions: [], totpVerified: true },
    });
    vi.spyOn(client, 'status').mockResolvedValue({ sampledAt: '2026-01-01T00:00:00Z', uptimeSeconds: 1, playersOnline: 1 });
    vi.spyOn(client, 'features').mockResolvedValue({ consoleEnabled: false, moderationEnabled: false, claimsEnabled: false, worldTrackingEnabled: false, rollbackEnabled: false });
    vi.spyOn(client, 'subscribe').mockReturnValue(() => undefined);
    vi.spyOn(client, 'players').mockResolvedValue({
      items: [{ uuid: '11111111-1111-1111-1111-111111111111', name: 'Alex', online: true }],
    });
    const action = vi.spyOn(client, 'playerAction')
      .mockResolvedValueOnce({
        id: 'preview-operation',
        kind: 'player.kick',
        state: 'PREVIEW_REQUIRED',
        previewToken: 'server-signed-preview',
        expiresAt: '2026-01-01T00:10:00Z',
        targets: [{ uuid: '11111111-1111-1111-1111-111111111111', name: 'Alex' }],
      })
      .mockResolvedValueOnce({ id: 'accepted-operation', kind: 'player.kick', state: 'QUEUED' });
    const user = userEvent.setup();

    render(<I18nProvider><ServerProvider client={client}><App /></ServerProvider></I18nProvider>);
    await user.click(await screen.findByRole('button', { name: 'Manage' }));
    expect(screen.getByRole('dialog').parentElement?.parentElement).toBe(document.body);
    await user.selectOptions(screen.getByLabelText('Action type'), 'kick');
    await user.type(screen.getByLabelText(/Audit reason/), 'Rule violation');
    await user.click(screen.getByRole('button', { name: 'Submit action' }));

    expect(await screen.findByText(/Alex · 11111111/)).toBeInTheDocument();
    expect(action).toHaveBeenNthCalledWith(1, '11111111-1111-1111-1111-111111111111', 'kick', {
      reason: 'Rule violation',
      value: undefined,
      confirmedTargetUuid: '11111111-1111-1111-1111-111111111111',
      previewToken: undefined,
    });

    await user.click(screen.getByRole('button', { name: 'Confirm' }));
    await waitFor(() => expect(action).toHaveBeenCalledTimes(2));
    expect(action).toHaveBeenNthCalledWith(2, '11111111-1111-1111-1111-111111111111', 'kick', {
      reason: 'Rule violation',
      value: undefined,
      confirmedTargetUuid: '11111111-1111-1111-1111-111111111111',
      previewToken: 'server-signed-preview',
    });
  });

  it('sends the supported whitelist mode through the destructive server preview', async () => {
    localStorage.setItem('xfesm.locale', 'en-US');
    location.hash = '/players';
    const client = new ApiClient();
    vi.spyOn(client, 'session').mockResolvedValue({ authenticated: true, csrfToken: 'csrf', actor: { id: 'owner-id', displayName: 'owner', roles: ['owner'], permissions: [], totpVerified: true } });
    vi.spyOn(client, 'status').mockResolvedValue({ sampledAt: '2026-01-01T00:00:00Z', uptimeSeconds: 1, playersOnline: 1 });
    vi.spyOn(client, 'features').mockResolvedValue({ consoleEnabled: false, moderationEnabled: false, claimsEnabled: false, worldTrackingEnabled: false, rollbackEnabled: false });
    vi.spyOn(client, 'subscribe').mockReturnValue(() => undefined);
    vi.spyOn(client, 'players').mockResolvedValue({ items: [{ uuid: '11111111-1111-1111-1111-111111111111', name: 'Alex', online: true }] });
    const action = vi.spyOn(client, 'playerAction').mockResolvedValue({ id: 'preview', kind: 'whitelist', state: 'PREVIEW_REQUIRED', previewToken: 'token' });
    const user = userEvent.setup();

    render(<I18nProvider><ServerProvider client={client}><App /></ServerProvider></I18nProvider>);
    await user.click(await screen.findByRole('button', { name: 'Manage' }));
    await user.selectOptions(screen.getByLabelText('Action type'), 'whitelist');
    await user.selectOptions(screen.getByLabelText('Whitelist operation'), 'remove');
    await user.type(screen.getByLabelText(/Audit reason/), 'Access revoked');
    await user.click(screen.getByRole('button', { name: 'Submit action' }));

    await waitFor(() => expect(action).toHaveBeenCalledOnce());
    expect(action).toHaveBeenCalledWith('11111111-1111-1111-1111-111111111111', 'whitelist', {
      reason: 'Access revoked',
      value: 'remove',
      confirmedTargetUuid: '11111111-1111-1111-1111-111111111111',
      previewToken: undefined,
    });
    expect(await screen.findByRole('button', { name: 'Confirm' })).toBeInTheDocument();
  });
});