diff --git a/frontend/src/second-edition/components/HarcosFegyverSpec.tsx b/frontend/src/second-edition/components/HarcosFegyverSpec.tsx index 4053dc7..ec78547 100644 --- a/frontend/src/second-edition/components/HarcosFegyverSpec.tsx +++ b/frontend/src/second-edition/components/HarcosFegyverSpec.tsx @@ -8,21 +8,23 @@ import {AppDispatch, RootState} from "../../store"; import {characterSelector, setHarcosSpecialization} from "../domain-models/characterSlice"; function HarcosFegyverSpecializacio(props: { - szint: number + harcosSzint: number, + karakterSzint: number, }) { const { - szint + harcosSzint, + karakterSzint, } = props const dispatch = useDispatch.withTypes()() const character = useSelector.withTypes()(characterSelector) - const specialization = character.szintlepesek[szint-1].harcosFegyver || 'kard_hosszu' + const specialization = character.szintlepesek[karakterSzint-1]?.harcosFegyver || 'kard_hosszu' const existingSpecializations = character.szintlepesek.filter(x => x.harcosFegyver != null).map(x => x.harcosFegyver! as string) - const changeSpecialization = (specialization: string) => dispatch(setHarcosSpecialization({szint, fegyver: specialization})) + const changeSpecialization = (specialization: string) => dispatch(setHarcosSpecialization({szint: karakterSzint, fegyver: specialization})) const fegyver = GetFegyver(specialization) const availableFegyverek = AllowedFegyver(Osztaly2E.Harcos) - const pickableFegyverek = availableFegyverek.filter(f => f.Id === specialization || existingSpecializations.filter(x => x === f.Id).length < (szint < 9 ? 1 : 2)) + const pickableFegyverek = availableFegyverek.filter(f => f.Id === specialization || existingSpecializations.filter(x => x === f.Id).length < (harcosSzint < 9 ? 1 : 2)) return <> @@ -32,7 +34,7 @@ function HarcosFegyverSpecializacio(props: { fegyverek={pickableFegyverek} selectedId={specialization} onChange={changeSpecialization} - dataTestId={"harcos-specialization-" + szint} + dataTestId={"harcos-specialization-" + karakterSzint} /> {fegyver == null && Ismeretlen fegyver: {specialization}} diff --git a/frontend/src/second-edition/components/LevelUps.test.tsx b/frontend/src/second-edition/components/LevelUps.test.tsx new file mode 100644 index 0000000..10fd337 --- /dev/null +++ b/frontend/src/second-edition/components/LevelUps.test.tsx @@ -0,0 +1,69 @@ +import React from "react"; +import {fireEvent, render} from "@testing-library/react"; +import {configureStore} from "@reduxjs/toolkit"; +import {Provider} from "react-redux"; +import LevelUps from "./LevelUps"; +import userReducer from "../../shared/domain-models/userSlice"; +import characterReducer, {setCharacter} from "../domain-models/characterSlice"; +import {AllowedFegyver} from "../domain-models/allowed-fegyver"; +import {Osztaly2E} from "../domain-models/osztaly2E"; +import {ChangeOsztalyAtSzint, DefaultKarakter, Karakter2E} from "../domain-models/karakter2E"; +import {LevelUp} from "../domain-models/szintlepes"; + +function applyLevelUp(karakter: Karakter2E): Karakter2E { + let next: Karakter2E | undefined; + LevelUp(karakter, updated => { + next = updated; + }); + expect(next).toBeDefined(); + return next as Karakter2E; +} + +describe("LevelUps Harcos specialization indexing", () => { + it("updates specialization on the selected character level for multiclass", async () => { + const level1Tolvaj: Karakter2E = { + ...DefaultKarakter, + szint: 1, + szintlepesek: [{ + osztaly: Osztaly2E.Tolvaj, + HProll: 6, + }], + tolvajKepzettsegek: [], + varazslatok: [], + }; + + const level2Auto = applyLevelUp(level1Tolvaj); + const karakter = ChangeOsztalyAtSzint(level2Auto, Osztaly2E.Harcos, 2); + + const store = configureStore({ + reducer: { + user: userReducer, + character2E: characterReducer, + }, + }); + store.dispatch(setCharacter(karakter)); + + const sut = render( + + store.dispatch(setCharacter(updated))} + /> + + ); + + const selector = await sut.findByTestId("harcos-specialization-2"); + + const currentSpec = karakter.szintlepesek[1]?.harcosFegyver; + const nextSpec = AllowedFegyver(Osztaly2E.Harcos) + .map(x => x.Id) + .find(id => id !== currentSpec); + + expect(nextSpec).toBeDefined(); + fireEvent.change(selector, {target: {value: nextSpec as string}}); + + const stateAfter = store.getState().character2E; + expect(stateAfter.szintlepesek[0]?.harcosFegyver).toBeUndefined(); + expect(stateAfter.szintlepesek[1]?.harcosFegyver).toBe(nextSpec); + }); +}); diff --git a/frontend/src/second-edition/components/LevelUps.tsx b/frontend/src/second-edition/components/LevelUps.tsx index 18330c5..16c0138 100644 --- a/frontend/src/second-edition/components/LevelUps.tsx +++ b/frontend/src/second-edition/components/LevelUps.tsx @@ -57,7 +57,7 @@ function LevelUp(props: { {szint % 4 === 0 && } @@ -69,12 +69,13 @@ function LevelUp(props: { /> {osztaly === Osztaly2E.Harcos && harcosSzint % 2 === 1 && } {osztaly === Osztaly2E.Tengeresz && kalozSzint % 3 === 0 && x.kalozKritikus)} changeKrit={changeKalozKritikus} szint={kalozSzint} @@ -82,12 +83,12 @@ function LevelUp(props: { } {osztaly === Osztaly2E.Tolvaj && (tolvajSzint === 5 || tolvajSzint === 9) - && szintlepes.tolvajExtraKepzettseg != null && + && szintlepes?.tolvajExtraKepzettseg != null &&
diff --git a/frontend/src/second-edition/domain-models/szintlepes.multiclass.test.ts b/frontend/src/second-edition/domain-models/szintlepes.multiclass.test.ts new file mode 100644 index 0000000..5bc6d9a --- /dev/null +++ b/frontend/src/second-edition/domain-models/szintlepes.multiclass.test.ts @@ -0,0 +1,60 @@ +import {ChangeOsztalyAtSzint, DefaultKarakter, Karakter2E} from "./karakter2E"; +import {Osztaly2E} from "./osztaly2E"; +import {LevelUp} from "./szintlepes"; + +function applyLevelUp(karakter: Karakter2E): Karakter2E { + let next: Karakter2E | undefined; + LevelUp(karakter, updated => { + next = updated; + }); + expect(next).toBeDefined(); + return next as Karakter2E; +} + +function level1Tolvaj(): Karakter2E { + return { + ...DefaultKarakter, + szint: 1, + szintlepesek: [{ + osztaly: Osztaly2E.Tolvaj, + HProll: 6, + }], + tolvajKepzettsegek: [], + varazslatok: [], + }; +} + +describe("Harcos specialization in multiclass level-ups", () => { + it("adds a specialization when first Harcos level is gained at character level 2", () => { + const afterLevel2 = applyLevelUp(level1Tolvaj()); + const multiclassed = ChangeOsztalyAtSzint(afterLevel2, Osztaly2E.Harcos, 2); + + const secondLevel = multiclassed.szintlepesek[1]; + expect(secondLevel?.osztaly).toBe(Osztaly2E.Harcos); + expect(secondLevel?.harcosFegyver).toBeDefined(); + }); + + it("does not add a specialization on even Harcos class level", () => { + const afterLevel2 = applyLevelUp(level1Tolvaj()); + const multiclassed = ChangeOsztalyAtSzint(afterLevel2, Osztaly2E.Harcos, 2); + const afterLevel3 = applyLevelUp(multiclassed); + + const thirdLevel = afterLevel3.szintlepesek[2]; + expect(thirdLevel?.osztaly).toBe(Osztaly2E.Harcos); + expect(thirdLevel?.harcosFegyver).toBeUndefined(); + }); + + it("adds the next specialization on odd Harcos class level after multiclass", () => { + const afterLevel2 = applyLevelUp(level1Tolvaj()); + const multiclassed = ChangeOsztalyAtSzint(afterLevel2, Osztaly2E.Harcos, 2); + const afterLevel3 = applyLevelUp(multiclassed); + const afterLevel4 = applyLevelUp(afterLevel3); + + const firstHarcosSpec = multiclassed.szintlepesek[1]?.harcosFegyver; + const thirdHarcosLevelSpec = afterLevel4.szintlepesek[3]?.harcosFegyver; + + expect(firstHarcosSpec).toBeDefined(); + expect(thirdHarcosLevelSpec).toBeDefined(); + expect(thirdHarcosLevelSpec).not.toBe(firstHarcosSpec); + }); +}); diff --git a/frontend/src/second-edition/pages/CreateCharacter2E.tsx b/frontend/src/second-edition/pages/CreateCharacter2E.tsx index cd86149..8a53151 100644 --- a/frontend/src/second-edition/pages/CreateCharacter2E.tsx +++ b/frontend/src/second-edition/pages/CreateCharacter2E.tsx @@ -109,7 +109,7 @@ function CreateCharacter2E(props: {

Tanult

- {karakter.szintlepesek[0].osztaly === Osztaly2E.Harcos && } + {karakter.szintlepesek[0].osztaly === Osztaly2E.Harcos && }
{/* 1. szinten */}