1
0
mirror of https://github.com/jcwimer/wrestlingApp synced 2026-04-11 16:01:56 +00:00
Files
wrestlingdev.com/test/javascript/controllers/match_data_controller.test.js

180 lines
5.9 KiB
JavaScript

import { beforeEach, describe, expect, it, vi } from "vitest"
import MatchDataController from "../../../app/assets/javascripts/controllers/match_data_controller.js"
function makeTarget(value = "") {
return {
value,
innerText: "",
addEventListener: vi.fn(),
classList: {
add: vi.fn(),
remove: vi.fn()
}
}
}
function buildController() {
const controller = new MatchDataController()
controller.tournamentIdValue = 8
controller.boutNumberValue = 1001
controller.matchIdValue = 22
controller.w1StatTarget = makeTarget("Initial W1")
controller.w2StatTarget = makeTarget("Initial W2")
controller.statusIndicatorTarget = makeTarget()
return controller
}
describe("match data controller", () => {
beforeEach(() => {
vi.restoreAllMocks()
vi.spyOn(Date.prototype, "toISOString").mockReturnValue("2026-04-10T00:00:00.000Z")
global.localStorage = {
getItem: vi.fn(() => null),
setItem: vi.fn()
}
global.window = {
App: null
}
global.document = {
getElementById: vi.fn(() => null)
}
global.setTimeout = vi.fn((fn) => {
fn()
return 1
})
global.clearTimeout = vi.fn()
global.setInterval = vi.fn(() => 123)
global.clearInterval = vi.fn()
})
it("connect initializes wrestler state, localStorage, textarea handlers, and subscription", () => {
const controller = buildController()
controller.initializeFromLocalStorage = vi.fn()
controller.setupSubscription = vi.fn()
controller.connect()
expect(controller.w1.stats).toBe("Initial W1")
expect(controller.w2.stats).toBe("Initial W2")
expect(controller.w1StatTarget.addEventListener).toHaveBeenCalledWith("input", expect.any(Function))
expect(controller.w2StatTarget.addEventListener).toHaveBeenCalledWith("input", expect.any(Function))
expect(controller.initializeFromLocalStorage).toHaveBeenCalledTimes(1)
expect(controller.setupSubscription).toHaveBeenCalledWith(22)
})
it("generates tournament and bout scoped localStorage keys", () => {
const controller = buildController()
expect(controller.generateKey("w1")).toBe("w1-8-1001")
expect(controller.generateKey("w2")).toBe("w2-8-1001")
})
it("updateStats updates textareas, localStorage, and sends websocket stat payloads", () => {
const controller = buildController()
controller.connect()
controller.matchSubscription = { perform: vi.fn() }
controller.updateStats(controller.w1, "T3")
expect(controller.w1.stats).toBe("Initial W1T3 ")
expect(controller.w1StatTarget.value).toBe("Initial W1T3 ")
expect(localStorage.setItem).toHaveBeenCalledWith(
"w1-8-1001",
expect.stringContaining('"stats":"Initial W1T3 "')
)
expect(controller.matchSubscription.perform).toHaveBeenCalledWith("send_stat", {
new_w1_stat: "Initial W1T3 "
})
})
it("textarea input saves local state and marks pending sync when disconnected", () => {
const controller = buildController()
controller.connect()
controller.isConnected = false
controller.matchSubscription = { perform: vi.fn() }
controller.handleTextAreaInput({ value: "Manual stat" }, controller.w2)
expect(controller.w2.stats).toBe("Manual stat")
expect(controller.pendingLocalSync.w2).toBe(true)
expect(localStorage.setItem).toHaveBeenCalledWith(
"w2-8-1001",
expect.stringContaining('"stats":"Manual stat"')
)
expect(controller.matchSubscription.perform).toHaveBeenCalledWith("send_stat", {
new_w2_stat: "Manual stat"
})
})
it("loads persisted localStorage stats and timers into the textareas", () => {
const controller = buildController()
localStorage.getItem = vi.fn((key) => {
if (key === "w1-8-1001") {
return JSON.stringify({
stats: "Saved W1",
updated_at: "timestamp",
timers: {
injury: { time: 5, startTime: null, interval: null },
blood: { time: 0, startTime: null, interval: null }
}
})
}
return null
})
controller.connect()
expect(controller.w1.stats).toBe("Saved W1")
expect(controller.w1StatTarget.value).toBe("Saved W1")
expect(controller.w1.timers.injury.time).toBe(5)
})
it("subscription callbacks update status, request sync, and apply received stats", () => {
const controller = buildController()
const subscription = { perform: vi.fn(), unsubscribe: vi.fn() }
let callbacks
global.App = {
cable: {
subscriptions: {
create: vi.fn((_identifier, receivedCallbacks) => {
callbacks = receivedCallbacks
return subscription
})
}
}
}
window.App = global.App
controller.connect()
controller.w1.stats = "Local W1"
controller.w2.stats = "Local W2"
callbacks.connected()
expect(controller.isConnected).toBe(true)
expect(controller.statusIndicatorTarget.innerText).toBe("Connected: Stats will update in real-time.")
expect(subscription.perform).toHaveBeenCalledWith("send_stat", {
new_w1_stat: "Local W1",
new_w2_stat: "Local W2"
})
controller.pendingLocalSync.w1 = false
controller.pendingLocalSync.w2 = false
callbacks.received({ w1_stat: "Remote W1", w2_stat: "Remote W2" })
expect(controller.w1StatTarget.value).toBe("Remote W1")
expect(controller.w2StatTarget.value).toBe("Remote W2")
callbacks.disconnected()
expect(controller.isConnected).toBe(false)
expect(controller.statusIndicatorTarget.innerText).toBe("Disconnected: Stats updates paused.")
})
it("setupSubscription reports websocket unavailable when ActionCable is missing", () => {
const controller = buildController()
controller.connect()
expect(controller.statusIndicatorTarget.innerText).toBe("Error: WebSockets unavailable. Stats won't update in real-time.")
expect(controller.statusIndicatorTarget.classList.add).toHaveBeenCalledWith("alert-danger")
})
})