Test mission skill modifiers

This commit is contained in:
2026-06-30 08:53:44 +02:00
parent 647869cba9
commit e7ef9ae2df
2 changed files with 56 additions and 3 deletions
+3 -1
View File
@@ -1212,6 +1212,7 @@ export default function MissionTab({ authedPlayer }) {
<div className="grid gap-2 rounded border border-slate-800 bg-slate-900/50 p-2">
<label className="text-xs font-semibold uppercase tracking-wide text-slate-400">Skill difficulty</label>
<select
aria-label="Skill difficulty"
value={state.skillDifficultyModifier}
onChange={e => setMiniState(sceneIndex, { skillDifficultyModifier: Number(e.target.value) })}
className="rounded border border-slate-600 bg-slate-900 px-2 py-2 text-sm"
@@ -1244,6 +1245,7 @@ export default function MissionTab({ authedPlayer }) {
<label className="grid gap-1 text-xs text-slate-400">
Custom modifier
<input
aria-label="Skill custom modifier"
type="number"
value={state.skillCustomModifier}
onChange={e => setMiniState(sceneIndex, { skillCustomModifier: Number(e.target.value || 0) })}
@@ -1262,7 +1264,7 @@ export default function MissionTab({ authedPlayer }) {
<div className="mt-2 rounded border border-cyan-900/50 bg-cyan-950/20 p-2">
<div className="flex items-center justify-between gap-2">
<span className="font-semibold uppercase tracking-wide text-cyan-200">Target Number</span>
<span className="text-lg font-bold tabular-nums text-cyan-100">{skillBreakdown.target}</span>
<span data-testid="skill-target-number" className="text-lg font-bold tabular-nums text-cyan-100">{skillBreakdown.target}</span>
</div>
<div className="mt-1 grid gap-1 text-slate-400">
<div>Base {skillBreakdown.characteristic}: <span className="text-slate-200">{skillBreakdown.base}</span></div>
+53 -2
View File
@@ -1,5 +1,5 @@
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
import axios from 'axios';
import MissionTab from '../components/MissionTab';
@@ -65,7 +65,7 @@ describe('MissionTab player view', () => {
expect(screen.getByText('The kill-team translates into a silent system.')).toBeInTheDocument();
expect(screen.getByText('Secure the landing zone')).toBeInTheDocument();
expect(screen.getByText('Spot movement')).toBeInTheDocument();
expect(screen.getAllByText('Spot movement').length).toBeGreaterThan(0);
expect(screen.getByText('Open in Dice Roller')).toBeInTheDocument();
expect(screen.queryByText('Table State')).not.toBeInTheDocument();
expect(screen.queryByText('GM')).not.toBeInTheDocument();
@@ -81,3 +81,54 @@ describe('MissionTab player view', () => {
expect(axios.get).not.toHaveBeenCalledWith('/api/missions/active/current');
});
});
describe('MissionTab mini skill modifiers', () => {
beforeEach(() => {
jest.clearAllMocks();
const activeMission = {
...mission,
scenes: [{
...mission.scenes[0],
checks: [
{ name: 'Spot movement', skill: 'Awareness', characteristic: 'Per', target: 45, modifier: 0, reward: 'Act before the ambush.' },
],
}],
};
axios.get.mockImplementation((url) => {
if (url === '/api/missions') return Promise.resolve({ data: [activeMission] });
if (url === '/api/missions/active/current') return Promise.resolve({ data: activeMission });
if (url === '/api/missions/active/rolls/feed?limit=50') return Promise.resolve({ data: [] });
if (url === '/api/players') return Promise.resolve({ data: [{ name: 'anders' }] });
if (url === '/api/players/anders') {
return Promise.resolve({
data: {
name: 'anders',
tabInfo: {
characteristics: { Per: 40 },
skills: { 'Awareness (Per)': { trained: true } },
wounds: { current: 20, total: 20 },
},
},
});
}
return Promise.resolve({ data: null });
});
});
test('uses skill difficulty and skill condition modifiers for a mission skill check target', async () => {
render(<MissionTab authedPlayer="gm" />);
await waitFor(() => expect(screen.getAllByText('Mini Roller').length).toBeGreaterThan(0));
await waitFor(() => expect(screen.getAllByTestId('skill-target-number')[0]).toHaveTextContent('40'));
fireEvent.change(screen.getAllByLabelText('Skill difficulty')[0], { target: { value: '30' } });
expect(screen.getAllByTestId('skill-target-number')[0]).toHaveTextContent('70');
fireEvent.click(screen.getAllByText('Poor/no tools -10')[0]);
expect(screen.getAllByTestId('skill-target-number')[0]).toHaveTextContent('60');
fireEvent.change(screen.getAllByLabelText('Skill custom modifier')[0], { target: { value: '-5' } });
expect(screen.getAllByTestId('skill-target-number')[0]).toHaveTextContent('55');
});
});