Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 97 additions & 17 deletions __tests__/controllers/message_controller_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,20 +254,47 @@ describe('MessageController', () => {
id: 'message-456',
product: undefined,
buttonId: undefined,
body: undefined,
body: '',
cardElement: cardWithoutData
}
})
})

it('handles null card element', () => {
it('falls back to button text when data text is missing', () => {
delete mockButton.dataset.text
mockButton.textContent = 'Buy this one'

controller.quickReply({ currentTarget: mockButton })

expect(controller.dispatch).toHaveBeenCalledWith('quickReply', {
detail: {
id: 'message-456',
product: 'product-456',
buttonId: 'btn-789',
body: 'Buy this one',
cardElement: mockCard
}
})
})

it('dispatches plain quick replies without a product card', () => {
mockButton.closest = jest.fn().mockReturnValue(null)

const mockEvent = {
currentTarget: mockButton
}

expect(() => controller.quickReply(mockEvent)).toThrow()
controller.quickReply(mockEvent)

expect(controller.dispatch).toHaveBeenCalledWith('quickReply', {
detail: {
id: 'message-456',
product: undefined,
buttonId: 'btn-789',
body: 'Buy Now',
cardElement: mockButton
}
})
})
})

Expand Down Expand Up @@ -394,8 +421,8 @@ describe('MessageController', () => {

describe('moveToLeft', () => {
beforeEach(() => {
// Mock getScrollAmount
controller.getScrollAmount = jest.fn().mockReturnValue(296)
mockCarouselContainer.scrollLeft = 350
controller.getPreviousPageScrollLeft = jest.fn().mockReturnValue(54)
})

it('scrolls left by calculated amount when carousel container exists', () => {
Expand All @@ -414,24 +441,23 @@ describe('MessageController', () => {
Object.defineProperty(tempController, 'hasCarouselContainerTarget', {
get: () => false
})
tempController.getScrollAmount = jest.fn().mockReturnValue(296)
tempController.getPreviousPageScrollLeft = jest.fn().mockReturnValue(54)

tempController.moveToLeft()

expect(mockCarouselContainer.scrollBy).not.toHaveBeenCalled()
})

it('calls getScrollAmount to calculate scroll distance', () => {
it('calls getPreviousPageScrollLeft to calculate scroll distance', () => {
controller.moveToLeft()

expect(controller.getScrollAmount).toHaveBeenCalledTimes(1)
expect(controller.getPreviousPageScrollLeft).toHaveBeenCalledTimes(1)
})
})

describe('moveToRight', () => {
beforeEach(() => {
// Mock getScrollAmount
controller.getScrollAmount = jest.fn().mockReturnValue(296)
controller.getNextPageScrollLeft = jest.fn().mockReturnValue(296)
})

it('scrolls right by calculated amount when carousel container exists', () => {
Expand All @@ -450,17 +476,17 @@ describe('MessageController', () => {
Object.defineProperty(tempController, 'hasCarouselContainerTarget', {
get: () => false
})
tempController.getScrollAmount = jest.fn().mockReturnValue(296)
tempController.getNextPageScrollLeft = jest.fn().mockReturnValue(296)

tempController.moveToRight()

expect(mockCarouselContainer.scrollBy).not.toHaveBeenCalled()
})

it('calls getScrollAmount to calculate scroll distance', () => {
it('calls getNextPageScrollLeft to calculate scroll distance', () => {
controller.moveToRight()

expect(controller.getScrollAmount).toHaveBeenCalledTimes(1)
expect(controller.getNextPageScrollLeft).toHaveBeenCalledTimes(1)
})
})

Expand Down Expand Up @@ -522,6 +548,60 @@ describe('MessageController', () => {
})
})

describe('getPageScrollAmount', () => {
it('uses the visible carousel area minus the gap', () => {
const result = controller.getPageScrollAmount()

expect(result).toBe(284)
})
})

describe('page scroll alignment', () => {
beforeEach(() => {
Object.defineProperty(mockCarouselContainer, 'clientWidth', {
value: 600,
writable: true,
configurable: true
})
Object.defineProperty(mockCarouselContainer, 'scrollWidth', {
value: 1244,
writable: true,
configurable: true
})
controller.pageStartOffsetValue = 56

mockCarouselContainer.innerHTML = ''

Array.from({ length: 4 }).forEach((_, index) => {
const card = document.createElement('article')
card.className = 'message__carousel_card'
Object.defineProperty(card, 'offsetWidth', {
value: 236,
writable: true,
configurable: true
})
Object.defineProperty(card, 'offsetLeft', {
value: index * 252,
writable: true,
configurable: true
})
mockCarouselContainer.appendChild(card)
})
})

it('aligns the next page to the first clipped card with a left offset', () => {
mockCarouselContainer.scrollLeft = 0

expect(controller.getNextPageScrollLeft()).toBe(448)
})

it('aligns the previous page back to the previous offset page', () => {
mockCarouselContainer.scrollLeft = 448

expect(controller.getPreviousPageScrollLeft()).toBe(0)
})
})

describe('updateFades', () => {
it('does nothing when carousel container target does not exist', () => {
// Create a new controller instance to avoid property redefinition issues
Expand Down Expand Up @@ -630,7 +710,7 @@ describe('MessageController', () => {

describe('edge case handling', () => {
it('handles rounding errors at end position', () => {
mockCarouselContainer.scrollLeft = 698 // 2 pixels before end, within tolerance
mockCarouselContainer.scrollLeft = 696 // 4 pixels before end, just outside the fade-hide threshold
Object.defineProperty(mockCarouselContainer, 'scrollWidth', {
value: 1000,
writable: true,
Expand All @@ -645,7 +725,7 @@ describe('MessageController', () => {

controller.updateFades()

// maxScroll = 1000 - 300 = 700, scrollLeft (698) < maxScroll - 1 (699), so right fade should be visible
// maxScroll = 1000 - 300 = 700, scrollLeft (696) keeps enough fade opacity to remain visible
expect(mockRightFade.classList.contains('hidden')).toBe(false)
})

Expand Down Expand Up @@ -694,7 +774,7 @@ describe('MessageController', () => {
describe('integration tests', () => {
it('updates fades correctly after moving left', () => {
mockCarouselContainer.scrollLeft = 350
controller.getScrollAmount = jest.fn().mockReturnValue(296)
controller.getPreviousPageScrollLeft = jest.fn().mockReturnValue(54)

const updateFadesSpy = jest.spyOn(controller, 'updateFades')

Expand All @@ -708,7 +788,7 @@ describe('MessageController', () => {

it('updates fades correctly after moving right', () => {
mockCarouselContainer.scrollLeft = 50
controller.getScrollAmount = jest.fn().mockReturnValue(296)
controller.getNextPageScrollLeft = jest.fn().mockReturnValue(346)

const updateFadesSpy = jest.spyOn(controller, 'updateFades')

Expand Down
Loading