From 32c4f7da5754e4e3e451bbdbca555ab1936b8dc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Wed, 22 Apr 2026 08:34:03 +0400 Subject: [PATCH] Add integration tests for carousel --- .../components/place-photos-carousel-test.gjs | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 tests/integration/components/place-photos-carousel-test.gjs diff --git a/tests/integration/components/place-photos-carousel-test.gjs b/tests/integration/components/place-photos-carousel-test.gjs new file mode 100644 index 0000000..72fc3cc --- /dev/null +++ b/tests/integration/components/place-photos-carousel-test.gjs @@ -0,0 +1,109 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'marco/tests/helpers'; +import { render, click } from '@ember/test-helpers'; +import PlacePhotosCarousel from 'marco/components/place-photos-carousel'; + +module('Integration | Component | place-photos-carousel', function (hooks) { + setupRenderingTest(hooks); + + test('it renders gracefully with no photos', async function (assert) { + this.photos = []; + + await render( + + ); + + assert + .dom('.place-photos-carousel-wrapper') + .doesNotExist('it does not render the wrapper when there are no photos'); + }); + + test('it renders a single photo without navigation chevrons', async function (assert) { + this.photos = [ + { + url: 'photo1.jpg', + thumbUrl: 'thumb1.jpg', + blurhash: 'L0000', + ratio: 1.5, + isLandscape: true, + }, + ]; + + await render( + + ); + + assert + .dom('.place-photos-carousel-wrapper') + .exists('it renders the wrapper'); + assert.dom('.carousel-slide').exists({ count: 1 }, 'it renders one slide'); + assert + .dom('img.place-header-photo') + .hasAttribute('src', 'photo1.jpg', 'it renders the photo'); + + // There should be no chevrons when there's only 1 photo + assert + .dom('.carousel-nav-btn') + .doesNotExist('it does not render chevrons for a single photo'); + }); + + test('it renders multiple photos and shows chevrons', async function (assert) { + this.photos = [ + { + url: 'photo1.jpg', + thumbUrl: 'thumb1.jpg', + blurhash: 'L0000', + ratio: 1.5, + isLandscape: true, + }, + { + url: 'photo2.jpg', + thumbUrl: 'thumb2.jpg', + blurhash: 'L1111', + ratio: 1.0, + isLandscape: false, + }, + { + url: 'photo3.jpg', + thumbUrl: 'thumb3.jpg', + blurhash: 'L2222', + ratio: 0.8, + isLandscape: false, + }, + ]; + + await render( + + ); + + await new Promise((resolve) => setTimeout(resolve, 100)); + + assert.dom('.carousel-slide').exists({ count: 3 }, 'it renders all slides'); + assert + .dom('.carousel-nav-btn') + .exists({ count: 2 }, 'it renders both chevrons'); + + // Initially, it shouldn't be able to scroll left + assert + .dom('.carousel-nav-btn.prev') + .hasClass('disabled', 'the prev button is disabled initially'); + assert + .dom('.carousel-nav-btn.next') + .doesNotHaveClass('disabled', 'the next button is enabled initially'); + + // We can't perfectly test native scroll behavior easily in JSDOM/QUnit without mocking the DOM elements' scroll properties, + // but we can test that clicking the next button triggers the scrolling method. + // However, since we mock scrollLeft in the component logic implicitly via template action, let's at least ensure clicking doesn't throw. + await click('.carousel-nav-btn.next'); + + assert.ok(true, 'clicking next button does not throw'); + }); +});