fix: Use BASE_ELEMENTS constant for debug unlock to prevent unlocking all 22 elements
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m18s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m18s
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { useManaStore } from '../stores/manaStore';
|
||||
import { ELEMENTS, BASE_UNLOCKED_ELEMENTS, BASE_ELEMENTS } from '../constants/elements';
|
||||
|
||||
// ─── Regression test: "Unlock All Base Elements" only unlocks 7 base ───────
|
||||
// Issue #374: Button was unlocking all 22 elements instead of just 7 base.
|
||||
|
||||
function resetManaStore() {
|
||||
useManaStore.setState({
|
||||
rawMana: 10000,
|
||||
meditateTicks: 0,
|
||||
totalManaGathered: 0,
|
||||
elements: Object.fromEntries(
|
||||
Object.keys(ELEMENTS).map(k => [
|
||||
k,
|
||||
{
|
||||
current: 0,
|
||||
max: 10,
|
||||
baseMax: 10,
|
||||
unlocked: BASE_UNLOCKED_ELEMENTS.includes(k),
|
||||
},
|
||||
])
|
||||
) as Record<string, { current: number; max: number; baseMax: number; unlocked: boolean }>,
|
||||
elementRegen: {},
|
||||
});
|
||||
}
|
||||
|
||||
describe('Unlock All Base Elements debug button', () => {
|
||||
beforeEach(() => {
|
||||
resetManaStore();
|
||||
});
|
||||
|
||||
it('BASE_ELEMENTS contains exactly 7 base elements', () => {
|
||||
expect(BASE_ELEMENTS).toHaveLength(7);
|
||||
expect(BASE_ELEMENTS).toContain('fire');
|
||||
expect(BASE_ELEMENTS).toContain('water');
|
||||
expect(BASE_ELEMENTS).toContain('air');
|
||||
expect(BASE_ELEMENTS).toContain('earth');
|
||||
expect(BASE_ELEMENTS).toContain('light');
|
||||
expect(BASE_ELEMENTS).toContain('dark');
|
||||
expect(BASE_ELEMENTS).toContain('death');
|
||||
});
|
||||
|
||||
it('BASE_ELEMENTS does NOT contain utility, composite, or exotic elements', () => {
|
||||
expect(BASE_ELEMENTS).not.toContain('transference');
|
||||
expect(BASE_ELEMENTS).not.toContain('metal');
|
||||
expect(BASE_ELEMENTS).not.toContain('sand');
|
||||
expect(BASE_ELEMENTS).not.toContain('lightning');
|
||||
expect(BASE_ELEMENTS).not.toContain('frost');
|
||||
expect(BASE_ELEMENTS).not.toContain('blackflame');
|
||||
expect(BASE_ELEMENTS).not.toContain('radiantflames');
|
||||
expect(BASE_ELEMENTS).not.toContain('miasma');
|
||||
expect(BASE_ELEMENTS).not.toContain('shadowglass');
|
||||
expect(BASE_ELEMENTS).not.toContain('crystal');
|
||||
expect(BASE_ELEMENTS).not.toContain('stellar');
|
||||
expect(BASE_ELEMENTS).not.toContain('void');
|
||||
expect(BASE_ELEMENTS).not.toContain('soul');
|
||||
expect(BASE_ELEMENTS).not.toContain('time');
|
||||
expect(BASE_ELEMENTS).not.toContain('plasma');
|
||||
});
|
||||
|
||||
it('unlockElement for all BASE_ELEMENTS only unlocks those 7', () => {
|
||||
const store = useManaStore.getState();
|
||||
|
||||
// All base elements should start locked (only transference is base-unlocked)
|
||||
BASE_ELEMENTS.forEach(e => {
|
||||
expect(store.elements[e]?.unlocked).toBe(false);
|
||||
});
|
||||
|
||||
// Unlock all base elements (cost 0, simulating debug button)
|
||||
BASE_ELEMENTS.forEach(e => {
|
||||
store.unlockElement(e, 0);
|
||||
});
|
||||
|
||||
const afterState = useManaStore.getState();
|
||||
|
||||
// All 7 base elements should now be unlocked
|
||||
BASE_ELEMENTS.forEach(e => {
|
||||
expect(afterState.elements[e]?.unlocked).toBe(true);
|
||||
});
|
||||
|
||||
// Non-base elements should NOT be unlocked
|
||||
const nonBaseElements = Object.keys(ELEMENTS).filter(
|
||||
e => !BASE_ELEMENTS.includes(e as never) && !BASE_UNLOCKED_ELEMENTS.includes(e)
|
||||
);
|
||||
nonBaseElements.forEach(e => {
|
||||
expect(afterState.elements[e]?.unlocked).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('debug handleUnlockBase does not unlock transference', () => {
|
||||
const store = useManaStore.getState();
|
||||
|
||||
// Verify transference starts unlocked
|
||||
expect(store.elements['transference']?.unlocked).toBe(true);
|
||||
|
||||
// Run the unlock logic
|
||||
BASE_ELEMENTS.forEach(e => {
|
||||
if (!store.elements[e]?.unlocked) {
|
||||
store.unlockElement(e, 0);
|
||||
}
|
||||
});
|
||||
|
||||
const afterState = useManaStore.getState();
|
||||
// transference was already unlocked, should still be unlocked
|
||||
expect(afterState.elements['transference']?.unlocked).toBe(true);
|
||||
// But no new utility elements were unlocked
|
||||
expect(afterState.elements['metal']?.unlocked).toBe(false);
|
||||
});
|
||||
|
||||
it('total unlocked count after unlock base is exactly 8 (7 base + transference)', () => {
|
||||
const store = useManaStore.getState();
|
||||
const unlockedBefore = Object.values(store.elements).filter(e => e.unlocked).length;
|
||||
// Only transference should be unlocked initially
|
||||
expect(unlockedBefore).toBe(1);
|
||||
|
||||
BASE_ELEMENTS.forEach(e => {
|
||||
store.unlockElement(e, 0);
|
||||
});
|
||||
|
||||
const afterState = useManaStore.getState();
|
||||
const unlockedAfter = Object.values(afterState.elements).filter(e => e.unlocked).length;
|
||||
expect(unlockedAfter).toBe(8); // 7 base + transference
|
||||
});
|
||||
});
|
||||
@@ -110,3 +110,6 @@ export const ELEMENT_ICON_NAMES: Record<string, string> = {
|
||||
|
||||
// ─── Base Unlocked Elements ───────────────────────────────────────────────────
|
||||
export const BASE_UNLOCKED_ELEMENTS = ['transference'];
|
||||
|
||||
// ─── Base Element IDs (7 base elements only — NOT composite/exotic/utility) ──
|
||||
export const BASE_ELEMENTS = ['fire', 'water', 'air', 'earth', 'light', 'dark', 'death'] as const;
|
||||
|
||||
@@ -8,7 +8,7 @@ export { getStudySpeedMultiplier, getStudyCostMultiplier } from './core';
|
||||
|
||||
// Element-related constants
|
||||
export { MANA_PER_ELEMENT, rawCost, elemCost, ELEMENTS, FLOOR_ELEM_CYCLE } from './elements';
|
||||
export { ELEMENT_OPPOSITES, ELEMENT_ICON_NAMES, BASE_UNLOCKED_ELEMENTS } from './elements';
|
||||
export { ELEMENT_OPPOSITES, ELEMENT_ICON_NAMES, BASE_UNLOCKED_ELEMENTS, BASE_ELEMENTS } from './elements';
|
||||
|
||||
// Spell constants
|
||||
export { SPELLS_DEF } from './spells';
|
||||
|
||||
Reference in New Issue
Block a user