@omnitronix/bonnys-fortune-game-engine 1.3.2 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/README.md +25 -15
  2. package/dist/__tests__/base-game.test.js +255 -0
  3. package/dist/__tests__/base-game.test.js.map +1 -0
  4. package/dist/__tests__/bonnys-fortune-v1.game-engine.test.js +1 -1
  5. package/dist/__tests__/bonus-handlers.test.js +303 -0
  6. package/dist/__tests__/bonus-handlers.test.js.map +1 -0
  7. package/dist/__tests__/bonus-meters.test.js +508 -0
  8. package/dist/__tests__/bonus-meters.test.js.map +1 -0
  9. package/dist/__tests__/collect-feature-handler.test.js +386 -0
  10. package/dist/__tests__/collect-feature-handler.test.js.map +1 -0
  11. package/dist/__tests__/comprehensive.test.js +747 -0
  12. package/dist/__tests__/comprehensive.test.js.map +1 -0
  13. package/dist/__tests__/error-paths.test.js +373 -0
  14. package/dist/__tests__/error-paths.test.js.map +1 -0
  15. package/dist/__tests__/helpers/test-engine-factory.js +268 -0
  16. package/dist/__tests__/helpers/test-engine-factory.js.map +1 -0
  17. package/dist/__tests__/rng-gli19-compliance.test.js +292 -0
  18. package/dist/__tests__/rng-gli19-compliance.test.js.map +1 -0
  19. package/dist/__tests__/rng-security.test.js +383 -0
  20. package/dist/__tests__/rng-security.test.js.map +1 -0
  21. package/dist/__tests__/rtp-simulation.test.js +242 -0
  22. package/dist/__tests__/rtp-simulation.test.js.map +1 -0
  23. package/dist/__tests__/state-transitions.test.js +307 -0
  24. package/dist/__tests__/state-transitions.test.js.map +1 -0
  25. package/dist/__tests__/steering-fortune-handler.test.js +286 -0
  26. package/dist/__tests__/steering-fortune-handler.test.js.map +1 -0
  27. package/dist/__tests__/symbol-distribution.test.js +195 -0
  28. package/dist/__tests__/symbol-distribution.test.js.map +1 -0
  29. package/dist/__tests__/treasure-hunt-handler.test.js +295 -0
  30. package/dist/__tests__/treasure-hunt-handler.test.js.map +1 -0
  31. package/dist/__tests__/win-calculator.test.js +515 -0
  32. package/dist/__tests__/win-calculator.test.js.map +1 -0
  33. package/dist/bonnys-fortune-v1.game-engine.js +14 -25
  34. package/dist/bonnys-fortune-v1.game-engine.js.map +1 -1
  35. package/dist/config/game-logic-config/game-logic-config.js +0 -2
  36. package/dist/config/game-logic-config/game-logic-config.js.map +1 -1
  37. package/dist/domain/types/{cheat-trigger-bonus-command.js → debug-trigger-bonus-command.js} +1 -1
  38. package/dist/domain/types/debug-trigger-bonus-command.js.map +1 -0
  39. package/dist/domain/types/{cheat-trigger-bonus-request.dto.js → debug-trigger-bonus-request.dto.js} +1 -1
  40. package/dist/domain/types/debug-trigger-bonus-request.dto.js.map +1 -0
  41. package/dist/domain/types/{cheat-update-bonus-meter-progress-command.js → debug-update-bonus-meter-progress-command.js} +1 -1
  42. package/dist/domain/types/debug-update-bonus-meter-progress-command.js.map +1 -0
  43. package/dist/domain/types/{cheat-update-bonus-meter-progress-request.dto.js → debug-update-bonus-meter-progress-request.dto.js} +1 -1
  44. package/dist/domain/types/debug-update-bonus-meter-progress-request.dto.js.map +1 -0
  45. package/dist/index.js.map +1 -1
  46. package/dist/logic/bonnys-fortune.game-logic.js +37 -17
  47. package/dist/logic/bonnys-fortune.game-logic.js.map +1 -1
  48. package/dist/logic/handlers/base-game.handler.js +1 -5
  49. package/dist/logic/handlers/base-game.handler.js.map +1 -1
  50. package/dist/rng/DummyRngClient.js +8 -1
  51. package/dist/rng/DummyRngClient.js.map +1 -1
  52. package/dist/rng/rng-client.factory.js.map +1 -1
  53. package/dist/validation/bonnys-fortune/bonnys-fortune-config.dto.js +0 -9
  54. package/dist/validation/bonnys-fortune/bonnys-fortune-config.dto.js.map +1 -1
  55. package/package.json +6 -6
  56. package/dist/__tests__/bonnys-fortune-v1.game-engine.test.d.ts +0 -1
  57. package/dist/bonnys-fortune-v1.game-engine.d.ts +0 -36
  58. package/dist/config/game-logic-config/file-system.game-logic-config-loader.d.ts +0 -4
  59. package/dist/config/game-logic-config/game-logic-config-loader.d.ts +0 -3
  60. package/dist/config/game-logic-config/game-logic-config.d.ts +0 -2
  61. package/dist/config/reel-strips-config/file-system.reel-strips-config-loader.d.ts +0 -4
  62. package/dist/config/reel-strips-config/reel-strip-option.dto.d.ts +0 -4
  63. package/dist/config/reel-strips-config/reel-strips-config-loader.d.ts +0 -3
  64. package/dist/config/reel-strips-config/reel-strips-config.dto.d.ts +0 -5
  65. package/dist/config/reel-strips-config/reel.dto.d.ts +0 -5
  66. package/dist/domain/game-round.types.d.ts +0 -9
  67. package/dist/domain/mappers/reel-strips-config.mapper.d.ts +0 -4
  68. package/dist/domain/reel-strip-option.d.ts +0 -7
  69. package/dist/domain/reel-strips-config.d.ts +0 -9
  70. package/dist/domain/reel.d.ts +0 -8
  71. package/dist/domain/types/cheat-trigger-bonus-command.d.ts +0 -5
  72. package/dist/domain/types/cheat-trigger-bonus-command.js.map +0 -1
  73. package/dist/domain/types/cheat-trigger-bonus-request.dto.d.ts +0 -5
  74. package/dist/domain/types/cheat-trigger-bonus-request.dto.js.map +0 -1
  75. package/dist/domain/types/cheat-update-bonus-meter-progress-command.d.ts +0 -5
  76. package/dist/domain/types/cheat-update-bonus-meter-progress-command.js.map +0 -1
  77. package/dist/domain/types/cheat-update-bonus-meter-progress-request.dto.d.ts +0 -5
  78. package/dist/domain/types/cheat-update-bonus-meter-progress-request.dto.js.map +0 -1
  79. package/dist/domain/types/game-spin-command.d.ts +0 -8
  80. package/dist/domain/types/game-spin-input.dto.d.ts +0 -8
  81. package/dist/domain/types/game-spin-output.dto.d.ts +0 -119
  82. package/dist/domain/types/game-symbols.response.dto.d.ts +0 -10
  83. package/dist/domain/types/reel-strip-option.dto.d.ts +0 -4
  84. package/dist/domain/types/reel-strips-config.dto.d.ts +0 -5
  85. package/dist/domain/types/reel.dto.d.ts +0 -5
  86. package/dist/domain/types/start-bonus-round-command.d.ts +0 -8
  87. package/dist/domain/types/start-bonus-round-input.dto.d.ts +0 -10
  88. package/dist/game-engine.interface.d.ts +0 -41
  89. package/dist/helpers/generate-hash.d.ts +0 -1
  90. package/dist/helpers/number-helper.d.ts +0 -23
  91. package/dist/helpers/optional-boolean-mapper.d.ts +0 -1
  92. package/dist/helpers/uuid-helper.d.ts +0 -3
  93. package/dist/helpers/validation-helper.d.ts +0 -14
  94. package/dist/index.d.ts +0 -2
  95. package/dist/logger/logger.d.ts +0 -22
  96. package/dist/logger/logger.js +0 -140
  97. package/dist/logger/logger.js.map +0 -1
  98. package/dist/logic/bonnys-fortune.game-logic.d.ts +0 -32
  99. package/dist/logic/bonnys-fortune.spin-generator.d.ts +0 -19
  100. package/dist/logic/bonnys-fortune.types.d.ts +0 -170
  101. package/dist/logic/bonnys-fortune.win-calculator.d.ts +0 -10
  102. package/dist/logic/game-logic-config.interface.d.ts +0 -180
  103. package/dist/logic/handlers/base-game.handler.d.ts +0 -15
  104. package/dist/logic/handlers/collect-feature-bonus.handler.d.ts +0 -13
  105. package/dist/logic/handlers/free-spins-bonus.handler.d.ts +0 -11
  106. package/dist/logic/handlers/steering-to-the-fortune-bonus.handler.d.ts +0 -11
  107. package/dist/logic/handlers/treasure-hunt-bonus.handler.d.ts +0 -15
  108. package/dist/rng/DummyRngClient.d.ts +0 -18
  109. package/dist/rng/rng-client.factory.d.ts +0 -7
  110. package/dist/rng/rng-client.interface.d.ts +0 -16
  111. package/dist/rng/rng-service.d.ts +0 -26
  112. package/dist/validation/abstract-game-logic-config.validator.d.ts +0 -4
  113. package/dist/validation/bonnys-fortune/bonnys-fortune-config.dto.d.ts +0 -131
  114. package/dist/validation/bonnys-fortune/bonnys-fortune-config.validator.d.ts +0 -5
  115. package/dist/validation/custom-decorators/IsNestedIntArray.d.ts +0 -2
  116. package/dist/validation/game-logic-config-validation.service.d.ts +0 -8
  117. package/dist/validation/reel-strips-config-validation.service.d.ts +0 -5
  118. package/src/__tests__/bonnys-fortune-v1.game-engine.test.ts +0 -80
  119. package/src/bonnys-fortune-v1.game-engine.ts +0 -314
  120. package/src/config/game-logic-config/file-system.game-logic-config-loader.ts +0 -27
  121. package/src/config/game-logic-config/game-logic-config-loader.ts +0 -3
  122. package/src/config/game-logic-config/game-logic-config.ts +0 -382
  123. package/src/config/reel-strips-config/file-system.reel-strips-config-loader.ts +0 -43
  124. package/src/config/reel-strips-config/reel-strip-option.dto.ts +0 -13
  125. package/src/config/reel-strips-config/reel-strips-config-loader.ts +0 -9
  126. package/src/config/reel-strips-config/reel-strips-config.dto.ts +0 -16
  127. package/src/config/reel-strips-config/reel.dto.ts +0 -16
  128. package/src/config/reel-strips-config/reels-BASE.csv +0 -52
  129. package/src/config/reel-strips-config/reels-BONUS.csv +0 -52
  130. package/src/domain/game-round.types.ts +0 -10
  131. package/src/domain/mappers/reel-strips-config.mapper.ts +0 -16
  132. package/src/domain/reel-strip-option.ts +0 -15
  133. package/src/domain/reel-strips-config.ts +0 -21
  134. package/src/domain/reel.ts +0 -17
  135. package/src/domain/types/cheat-trigger-bonus-command.ts +0 -5
  136. package/src/domain/types/cheat-trigger-bonus-request.dto.ts +0 -5
  137. package/src/domain/types/cheat-update-bonus-meter-progress-command.ts +0 -6
  138. package/src/domain/types/cheat-update-bonus-meter-progress-request.dto.ts +0 -5
  139. package/src/domain/types/game-spin-command.ts +0 -8
  140. package/src/domain/types/game-spin-input.dto.ts +0 -8
  141. package/src/domain/types/game-spin-output.dto.ts +0 -142
  142. package/src/domain/types/game-symbols.response.dto.ts +0 -11
  143. package/src/domain/types/reel-strip-option.dto.ts +0 -13
  144. package/src/domain/types/reel-strips-config.dto.ts +0 -15
  145. package/src/domain/types/reel.dto.ts +0 -15
  146. package/src/domain/types/start-bonus-round-command.ts +0 -8
  147. package/src/domain/types/start-bonus-round-input.dto.ts +0 -10
  148. package/src/game-engine.interface.ts +0 -59
  149. package/src/helpers/generate-hash.ts +0 -5
  150. package/src/helpers/number-helper.ts +0 -41
  151. package/src/helpers/optional-boolean-mapper.ts +0 -5
  152. package/src/helpers/uuid-helper.ts +0 -7
  153. package/src/helpers/validation-helper.ts +0 -27
  154. package/src/index.ts +0 -3
  155. package/src/logger/logger.ts +0 -178
  156. package/src/logic/bonnys-fortune.game-logic.ts +0 -490
  157. package/src/logic/bonnys-fortune.spin-generator.ts +0 -277
  158. package/src/logic/bonnys-fortune.types.ts +0 -223
  159. package/src/logic/bonnys-fortune.win-calculator.ts +0 -210
  160. package/src/logic/game-logic-config.interface.ts +0 -176
  161. package/src/logic/handlers/base-game.handler.ts +0 -221
  162. package/src/logic/handlers/collect-feature-bonus.handler.ts +0 -301
  163. package/src/logic/handlers/free-spins-bonus.handler.ts +0 -119
  164. package/src/logic/handlers/steering-to-the-fortune-bonus.handler.ts +0 -118
  165. package/src/logic/handlers/treasure-hunt-bonus.handler.ts +0 -232
  166. package/src/rng/DummyRngClient.ts +0 -108
  167. package/src/rng/rng-client.factory.ts +0 -27
  168. package/src/rng/rng-client.interface.ts +0 -38
  169. package/src/rng/rng-service.ts +0 -130
  170. package/src/validation/abstract-game-logic-config.validator.ts +0 -20
  171. package/src/validation/bonnys-fortune/bonnys-fortune-config.dto.ts +0 -379
  172. package/src/validation/bonnys-fortune/bonnys-fortune-config.validator.ts +0 -8
  173. package/src/validation/custom-decorators/IsNestedIntArray.ts +0 -29
  174. package/src/validation/game-logic-config-validation.service.ts +0 -28
  175. package/src/validation/reel-strips-config-validation.service.ts +0 -29
@@ -0,0 +1,303 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Bonus Handler Tests — Bonnys Fortune
5
+ *
6
+ * Tests all 4 bonus types via debug trigger:
7
+ * - Treasure Hunt (bonusGame1): pick mechanic, jackpots
8
+ * - Free Spins (bonusGame2): ways evaluation, multipliers
9
+ * - Steering Fortune (bonusGame3): wheel spin, prize resolution
10
+ * - Collect Feature (collectFeature): symbol collection, checkpoints
11
+ * - Debug trigger → START_BONUS_ROUND flow
12
+ * - Meter redraw after bonus completion
13
+ */
14
+ const test_engine_factory_1 = require("./helpers/test-engine-factory");
15
+ describe('Bonus Handlers — Bonnys Fortune', () => {
16
+ beforeEach(() => {
17
+ (0, test_engine_factory_1.resetCommandIdCounter)();
18
+ });
19
+ describe('Treasure Hunt (bonusGame1)', () => {
20
+ it('should trigger treasure hunt via debug successfully', async () => {
21
+ const engine = (0, test_engine_factory_1.createEngine)();
22
+ const session = await (0, test_engine_factory_1.initSession)(engine);
23
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'bonusGame1');
24
+ expect(debugResult.success).toBe(true);
25
+ // Debug trigger adds exactly 1 pending bonus
26
+ expect(debugResult.privateState.pendingBonuses.length).toBe(1);
27
+ });
28
+ it('should complete treasure hunt and return to BASE_GAME_SPIN', async () => {
29
+ const engine = (0, test_engine_factory_1.createEngine)();
30
+ const session = await (0, test_engine_factory_1.initSession)(engine);
31
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'bonusGame1');
32
+ if (!debugResult.success)
33
+ return;
34
+ const bonus = debugResult.privateState.pendingBonuses[0];
35
+ const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, debugResult.publicState, debugResult.privateState, bonus.bonusType);
36
+ expect(bonusResult.success).toBe(true);
37
+ // BF generates all bonus results upfront — final state is in last result
38
+ const finalState = (0, test_engine_factory_1.extractFinalBonusState)(bonusResult);
39
+ expect(finalState.privateState.nextSpinType).toBe('BASE_GAME_SPIN');
40
+ });
41
+ it('should produce non-negative winnings from treasure hunt', async () => {
42
+ const engine = (0, test_engine_factory_1.createEngine)();
43
+ const session = await (0, test_engine_factory_1.initSession)(engine);
44
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'bonusGame1');
45
+ if (!debugResult.success)
46
+ return;
47
+ const bonus = debugResult.privateState.pendingBonuses[0];
48
+ const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, debugResult.publicState, debugResult.privateState, bonus.bonusType);
49
+ expect(bonusResult.success).toBe(true);
50
+ if (bonusResult.outcome) {
51
+ const outcomes = Array.isArray(bonusResult.outcome)
52
+ ? bonusResult.outcome
53
+ : [bonusResult.outcome];
54
+ for (const o of outcomes) {
55
+ if (o.playerWinning !== undefined) {
56
+ expect(o.playerWinning).toBeGreaterThanOrEqual(0);
57
+ }
58
+ }
59
+ }
60
+ });
61
+ it('should include RNG outcome in treasure hunt', async () => {
62
+ const engine = (0, test_engine_factory_1.createEngine)();
63
+ const session = await (0, test_engine_factory_1.initSession)(engine);
64
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'bonusGame1');
65
+ if (!debugResult.success)
66
+ return;
67
+ const bonus = debugResult.privateState.pendingBonuses[0];
68
+ const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, debugResult.publicState, debugResult.privateState, bonus.bonusType);
69
+ expect(bonusResult.success).toBe(true);
70
+ expect(bonusResult.rngOutcome).toBeDefined();
71
+ expect(typeof bonusResult.rngOutcome).toBe('object');
72
+ expect(Object.keys(bonusResult.rngOutcome || {}).length).toBeGreaterThan(0);
73
+ });
74
+ });
75
+ describe('Free Spins (bonusGame2)', () => {
76
+ it('should trigger free spins via debug successfully', async () => {
77
+ const engine = (0, test_engine_factory_1.createEngine)();
78
+ const session = await (0, test_engine_factory_1.initSession)(engine);
79
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'bonusGame2');
80
+ expect(debugResult.success).toBe(true);
81
+ // Debug trigger adds exactly 1 pending bonus
82
+ expect(debugResult.privateState.pendingBonuses.length).toBe(1);
83
+ });
84
+ it('should complete free spins and return to BASE_GAME_SPIN', async () => {
85
+ const engine = (0, test_engine_factory_1.createEngine)();
86
+ const session = await (0, test_engine_factory_1.initSession)(engine);
87
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'bonusGame2');
88
+ if (!debugResult.success)
89
+ return;
90
+ const bonus = debugResult.privateState.pendingBonuses[0];
91
+ const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, debugResult.publicState, debugResult.privateState, bonus.bonusType);
92
+ expect(bonusResult.success).toBe(true);
93
+ // BF generates all bonus results upfront — final state is in last result
94
+ const finalState = (0, test_engine_factory_1.extractFinalBonusState)(bonusResult);
95
+ expect(finalState.privateState.nextSpinType).toBe('BASE_GAME_SPIN');
96
+ });
97
+ it('should produce non-negative winnings from free spins', async () => {
98
+ const engine = (0, test_engine_factory_1.createEngine)();
99
+ const session = await (0, test_engine_factory_1.initSession)(engine);
100
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'bonusGame2');
101
+ if (!debugResult.success)
102
+ return;
103
+ const bonus = debugResult.privateState.pendingBonuses[0];
104
+ const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, debugResult.publicState, debugResult.privateState, bonus.bonusType);
105
+ expect(bonusResult.success).toBe(true);
106
+ if (bonusResult.outcome) {
107
+ const outcomes = Array.isArray(bonusResult.outcome)
108
+ ? bonusResult.outcome
109
+ : [bonusResult.outcome];
110
+ for (const o of outcomes) {
111
+ if (o.playerWinning !== undefined) {
112
+ expect(o.playerWinning).toBeGreaterThanOrEqual(0);
113
+ }
114
+ }
115
+ }
116
+ });
117
+ });
118
+ describe('Steering Fortune (bonusGame3)', () => {
119
+ it('should trigger steering fortune via debug successfully', async () => {
120
+ const engine = (0, test_engine_factory_1.createEngine)();
121
+ const session = await (0, test_engine_factory_1.initSession)(engine);
122
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'bonusGame3');
123
+ expect(debugResult.success).toBe(true);
124
+ // Debug trigger adds exactly 1 pending bonus
125
+ expect(debugResult.privateState.pendingBonuses.length).toBe(1);
126
+ });
127
+ it('should complete steering fortune', async () => {
128
+ const engine = (0, test_engine_factory_1.createEngine)();
129
+ const session = await (0, test_engine_factory_1.initSession)(engine);
130
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'bonusGame3');
131
+ if (!debugResult.success)
132
+ return;
133
+ const bonus = debugResult.privateState.pendingBonuses[0];
134
+ const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, debugResult.publicState, debugResult.privateState, bonus.bonusType);
135
+ expect(bonusResult.success).toBe(true);
136
+ // Steering Fortune may chain to another bonus type
137
+ const finalState = (0, test_engine_factory_1.extractFinalBonusState)(bonusResult);
138
+ expect(finalState.privateState.nextSpinType).toBeDefined();
139
+ });
140
+ it('should handle steering fortune chaining to another bonus', async () => {
141
+ const engine = (0, test_engine_factory_1.createEngine)();
142
+ const session = await (0, test_engine_factory_1.initSession)(engine);
143
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'bonusGame3');
144
+ if (!debugResult.success)
145
+ return;
146
+ const bonus = debugResult.privateState.pendingBonuses[0];
147
+ const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, debugResult.publicState, debugResult.privateState, bonus.bonusType);
148
+ expect(bonusResult.success).toBe(true);
149
+ // If it chained to another bonus, complete that too
150
+ const finalState = (0, test_engine_factory_1.extractFinalBonusState)(bonusResult);
151
+ if (finalState.privateState.pendingBonuses?.length > 0) {
152
+ const nextBonus = finalState.privateState.pendingBonuses[0];
153
+ const nextResult = await (0, test_engine_factory_1.startBonusRound)(engine, finalState.publicState, finalState.privateState, nextBonus.bonusType);
154
+ expect(nextResult.success).toBe(true);
155
+ }
156
+ });
157
+ });
158
+ describe('Collect Feature (collectFeature)', () => {
159
+ it('should trigger collect feature via debug successfully', async () => {
160
+ const engine = (0, test_engine_factory_1.createEngine)();
161
+ const session = await (0, test_engine_factory_1.initSession)(engine);
162
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'collectFeature');
163
+ expect(debugResult.success).toBe(true);
164
+ // Debug trigger adds exactly 1 pending bonus
165
+ expect(debugResult.privateState.pendingBonuses.length).toBe(1);
166
+ });
167
+ it('should complete collect feature and return to BASE_GAME_SPIN', async () => {
168
+ const engine = (0, test_engine_factory_1.createEngine)();
169
+ const session = await (0, test_engine_factory_1.initSession)(engine);
170
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'collectFeature');
171
+ if (!debugResult.success)
172
+ return;
173
+ const bonus = debugResult.privateState.pendingBonuses[0];
174
+ const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, debugResult.publicState, debugResult.privateState, bonus.bonusType);
175
+ expect(bonusResult.success).toBe(true);
176
+ // BF generates all bonus results upfront — final state is in last result
177
+ const finalState = (0, test_engine_factory_1.extractFinalBonusState)(bonusResult);
178
+ expect(finalState.privateState.nextSpinType).toBe('BASE_GAME_SPIN');
179
+ });
180
+ it('should produce non-negative winnings from collect feature', async () => {
181
+ const engine = (0, test_engine_factory_1.createEngine)();
182
+ const session = await (0, test_engine_factory_1.initSession)(engine);
183
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'collectFeature');
184
+ if (!debugResult.success)
185
+ return;
186
+ const bonus = debugResult.privateState.pendingBonuses[0];
187
+ const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, debugResult.publicState, debugResult.privateState, bonus.bonusType);
188
+ expect(bonusResult.success).toBe(true);
189
+ if (bonusResult.outcome) {
190
+ const outcomes = Array.isArray(bonusResult.outcome)
191
+ ? bonusResult.outcome
192
+ : [bonusResult.outcome];
193
+ for (const o of outcomes) {
194
+ if (o.playerWinning !== undefined) {
195
+ expect(o.playerWinning).toBeGreaterThanOrEqual(0);
196
+ }
197
+ }
198
+ }
199
+ });
200
+ });
201
+ describe('Meter Redraw After Bonus', () => {
202
+ it('should redraw meter after non-collectFeature bonus', async () => {
203
+ const engine = (0, test_engine_factory_1.createEngine)();
204
+ const session = await (0, test_engine_factory_1.initSession)(engine);
205
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'bonusGame1');
206
+ if (!debugResult.success)
207
+ return;
208
+ const bonus = debugResult.privateState.pendingBonuses[0];
209
+ const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, debugResult.publicState, debugResult.privateState, bonus.bonusType);
210
+ expect(bonusResult.success).toBe(true);
211
+ // After bonus, meters should be valid (may have been redrawn)
212
+ const finalMeters = bonusResult.publicState.bonusMeters;
213
+ expect(finalMeters).toBeDefined();
214
+ expect(typeof finalMeters).toBe('object');
215
+ // Should have 3 meters (bonusGame1, bonusGame2, bonusGame3)
216
+ expect(Object.keys(finalMeters || {}).length).toBe(3);
217
+ for (const [, meter] of Object.entries(finalMeters || {})) {
218
+ const m = meter;
219
+ expect(m.threshold).toBeGreaterThan(0);
220
+ expect(m.progress).toBeGreaterThanOrEqual(0);
221
+ }
222
+ });
223
+ });
224
+ describe('Post-Bonus Play', () => {
225
+ it('should allow normal spin after treasure hunt', async () => {
226
+ const engine = (0, test_engine_factory_1.createEngine)();
227
+ const session = await (0, test_engine_factory_1.initSession)(engine);
228
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'bonusGame1');
229
+ if (!debugResult.success)
230
+ return;
231
+ const bonus = debugResult.privateState.pendingBonuses[0];
232
+ const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, debugResult.publicState, debugResult.privateState, bonus.bonusType);
233
+ expect(bonusResult.success).toBe(true);
234
+ const finalState1 = (0, test_engine_factory_1.extractFinalBonusState)(bonusResult);
235
+ if (finalState1.privateState.nextSpinType === 'BASE_GAME_SPIN') {
236
+ const spinResult = await (0, test_engine_factory_1.executeSpin)(engine, finalState1.publicState, finalState1.privateState);
237
+ expect(spinResult.success).toBe(true);
238
+ }
239
+ });
240
+ it('should allow normal spin after free spins', async () => {
241
+ const engine = (0, test_engine_factory_1.createEngine)();
242
+ const session = await (0, test_engine_factory_1.initSession)(engine);
243
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'bonusGame2');
244
+ if (!debugResult.success)
245
+ return;
246
+ const bonus = debugResult.privateState.pendingBonuses[0];
247
+ const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, debugResult.publicState, debugResult.privateState, bonus.bonusType);
248
+ expect(bonusResult.success).toBe(true);
249
+ const finalState2 = (0, test_engine_factory_1.extractFinalBonusState)(bonusResult);
250
+ if (finalState2.privateState.nextSpinType === 'BASE_GAME_SPIN') {
251
+ const spinResult = await (0, test_engine_factory_1.executeSpin)(engine, finalState2.publicState, finalState2.privateState);
252
+ expect(spinResult.success).toBe(true);
253
+ }
254
+ });
255
+ it('should allow normal spin after collect feature', async () => {
256
+ const engine = (0, test_engine_factory_1.createEngine)();
257
+ const session = await (0, test_engine_factory_1.initSession)(engine);
258
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'collectFeature');
259
+ if (!debugResult.success)
260
+ return;
261
+ const bonus = debugResult.privateState.pendingBonuses[0];
262
+ const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, debugResult.publicState, debugResult.privateState, bonus.bonusType);
263
+ expect(bonusResult.success).toBe(true);
264
+ const finalState3 = (0, test_engine_factory_1.extractFinalBonusState)(bonusResult);
265
+ if (finalState3.privateState.nextSpinType === 'BASE_GAME_SPIN') {
266
+ const spinResult = await (0, test_engine_factory_1.executeSpin)(engine, finalState3.publicState, finalState3.privateState);
267
+ expect(spinResult.success).toBe(true);
268
+ }
269
+ });
270
+ });
271
+ describe('Debug Trigger Mechanics', () => {
272
+ it('should support all 4 bonus types via debug', async () => {
273
+ const types = ['bonusGame1', 'bonusGame2', 'bonusGame3', 'collectFeature'];
274
+ for (const type of types) {
275
+ const engine = (0, test_engine_factory_1.createEngine)();
276
+ const session = await (0, test_engine_factory_1.initSession)(engine);
277
+ const result = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, type);
278
+ expect(result.success).toBe(true);
279
+ }
280
+ });
281
+ it('should add bonus to pending list with valid bonusId', async () => {
282
+ const engine = (0, test_engine_factory_1.createEngine)();
283
+ const session = await (0, test_engine_factory_1.initSession)(engine);
284
+ const result = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'bonusGame1');
285
+ expect(result.success).toBe(true);
286
+ const bonus = result.privateState.pendingBonuses[0];
287
+ expect(bonus).toBeDefined();
288
+ expect(bonus.bonusId).toBeDefined();
289
+ expect(typeof bonus.bonusId).toBe('string');
290
+ // UUID format: at least 32 characters (without dashes) or 36 with dashes
291
+ expect(bonus.bonusId.length).toBeGreaterThanOrEqual(32);
292
+ });
293
+ it('should preserve bet amount in triggered bonus', async () => {
294
+ const engine = (0, test_engine_factory_1.createEngine)();
295
+ const session = await (0, test_engine_factory_1.initSession)(engine, 5.0);
296
+ const result = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, 'bonusGame1', 5.0);
297
+ expect(result.success).toBe(true);
298
+ const bonus = result.privateState.pendingBonuses[0];
299
+ expect(bonus.betAmount).toBe(5.0);
300
+ });
301
+ });
302
+ });
303
+ //# sourceMappingURL=bonus-handlers.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bonus-handlers.test.js","sourceRoot":"","sources":["../../src/__tests__/bonus-handlers.test.ts"],"names":[],"mappings":"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"}