241 lines
10 KiB
JavaScript
241 lines
10 KiB
JavaScript
/**
|
|
* QUnit Tests for Realtime Search Functionality
|
|
* Tests product filtering and search behavior
|
|
*/
|
|
|
|
odoo.define('website_sale_aplicoop.test_realtime_search', function (require) {
|
|
'use strict';
|
|
|
|
var QUnit = window.QUnit;
|
|
|
|
QUnit.module('website_sale_aplicoop.realtime_search', {
|
|
beforeEach: function() {
|
|
// Setup: Create test DOM with product cards
|
|
this.$fixture = $('#qunit-fixture');
|
|
|
|
this.$fixture.append(
|
|
'<input type="text" id="realtime-search-input" />' +
|
|
'<select id="realtime-category-select">' +
|
|
'<option value="">All Categories</option>' +
|
|
'<option value="1">Category 1</option>' +
|
|
'<option value="2">Category 2</option>' +
|
|
'</select>' +
|
|
'<div class="product-card" data-product-name="Cabbage" data-category-id="1"></div>' +
|
|
'<div class="product-card" data-product-name="Carrot" data-category-id="1"></div>' +
|
|
'<div class="product-card" data-product-name="Apple" data-category-id="2"></div>' +
|
|
'<div class="product-card" data-product-name="Banana" data-category-id="2"></div>'
|
|
);
|
|
|
|
// Initialize search object
|
|
window.realtimeSearch = {
|
|
searchInput: document.getElementById('realtime-search-input'),
|
|
categorySelect: document.getElementById('realtime-category-select'),
|
|
productCards: document.querySelectorAll('.product-card'),
|
|
|
|
filterProducts: function() {
|
|
var searchTerm = this.searchInput.value.toLowerCase().trim();
|
|
var selectedCategory = this.categorySelect.value;
|
|
|
|
var visibleCount = 0;
|
|
var hiddenCount = 0;
|
|
|
|
this.productCards.forEach(function(card) {
|
|
var productName = card.getAttribute('data-product-name').toLowerCase();
|
|
var categoryId = card.getAttribute('data-category-id');
|
|
|
|
var matchesSearch = !searchTerm || productName.includes(searchTerm);
|
|
var matchesCategory = !selectedCategory || categoryId === selectedCategory;
|
|
|
|
if (matchesSearch && matchesCategory) {
|
|
card.classList.remove('d-none');
|
|
visibleCount++;
|
|
} else {
|
|
card.classList.add('d-none');
|
|
hiddenCount++;
|
|
}
|
|
});
|
|
|
|
return { visible: visibleCount, hidden: hiddenCount };
|
|
}
|
|
};
|
|
},
|
|
afterEach: function() {
|
|
// Cleanup
|
|
this.$fixture.empty();
|
|
delete window.realtimeSearch;
|
|
}
|
|
}, function() {
|
|
|
|
QUnit.test('search input element exists', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var searchInput = document.getElementById('realtime-search-input');
|
|
assert.ok(searchInput, 'search input element exists');
|
|
});
|
|
|
|
QUnit.test('category select element exists', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var categorySelect = document.getElementById('realtime-category-select');
|
|
assert.ok(categorySelect, 'category select element exists');
|
|
});
|
|
|
|
QUnit.test('product cards are found', function(assert) {
|
|
assert.expect(1);
|
|
|
|
var productCards = document.querySelectorAll('.product-card');
|
|
assert.equal(productCards.length, 4, 'found 4 product cards');
|
|
});
|
|
|
|
QUnit.test('search filters by product name', function(assert) {
|
|
assert.expect(2);
|
|
|
|
// Search for "cab"
|
|
window.realtimeSearch.searchInput.value = 'cab';
|
|
var result = window.realtimeSearch.filterProducts();
|
|
|
|
assert.equal(result.visible, 1, '1 product visible (Cabbage)');
|
|
assert.equal(result.hidden, 3, '3 products hidden');
|
|
});
|
|
|
|
QUnit.test('search is case insensitive', function(assert) {
|
|
assert.expect(2);
|
|
|
|
// Search for "CARROT" in uppercase
|
|
window.realtimeSearch.searchInput.value = 'CARROT';
|
|
var result = window.realtimeSearch.filterProducts();
|
|
|
|
assert.equal(result.visible, 1, '1 product visible (Carrot)');
|
|
assert.equal(result.hidden, 3, '3 products hidden');
|
|
});
|
|
|
|
QUnit.test('empty search shows all products', function(assert) {
|
|
assert.expect(2);
|
|
|
|
window.realtimeSearch.searchInput.value = '';
|
|
var result = window.realtimeSearch.filterProducts();
|
|
|
|
assert.equal(result.visible, 4, 'all 4 products visible');
|
|
assert.equal(result.hidden, 0, 'no products hidden');
|
|
});
|
|
|
|
QUnit.test('category filter works', function(assert) {
|
|
assert.expect(2);
|
|
|
|
// Select category 1
|
|
window.realtimeSearch.categorySelect.value = '1';
|
|
var result = window.realtimeSearch.filterProducts();
|
|
|
|
assert.equal(result.visible, 2, '2 products visible (Cabbage, Carrot)');
|
|
assert.equal(result.hidden, 2, '2 products hidden (Apple, Banana)');
|
|
});
|
|
|
|
QUnit.test('search and category filter work together', function(assert) {
|
|
assert.expect(2);
|
|
|
|
// Search for "ca" in category 1
|
|
window.realtimeSearch.searchInput.value = 'ca';
|
|
window.realtimeSearch.categorySelect.value = '1';
|
|
var result = window.realtimeSearch.filterProducts();
|
|
|
|
// Should show: Cabbage, Carrot (both in category 1 and match "ca")
|
|
assert.equal(result.visible, 2, '2 products visible');
|
|
assert.equal(result.hidden, 2, '2 products hidden');
|
|
});
|
|
|
|
QUnit.test('search for non-existent product shows none', function(assert) {
|
|
assert.expect(2);
|
|
|
|
window.realtimeSearch.searchInput.value = 'xyz123';
|
|
var result = window.realtimeSearch.filterProducts();
|
|
|
|
assert.equal(result.visible, 0, 'no products visible');
|
|
assert.equal(result.hidden, 4, 'all 4 products hidden');
|
|
});
|
|
|
|
QUnit.test('partial match works', function(assert) {
|
|
assert.expect(2);
|
|
|
|
// Search for "an" should match "Banana"
|
|
window.realtimeSearch.searchInput.value = 'an';
|
|
var result = window.realtimeSearch.filterProducts();
|
|
|
|
assert.equal(result.visible, 1, '1 product visible (Banana)');
|
|
assert.equal(result.hidden, 3, '3 products hidden');
|
|
});
|
|
|
|
QUnit.test('search trims whitespace', function(assert) {
|
|
assert.expect(2);
|
|
|
|
// Search with extra whitespace
|
|
window.realtimeSearch.searchInput.value = ' apple ';
|
|
var result = window.realtimeSearch.filterProducts();
|
|
|
|
assert.equal(result.visible, 1, '1 product visible (Apple)');
|
|
assert.equal(result.hidden, 3, '3 products hidden');
|
|
});
|
|
|
|
QUnit.test('d-none class is added to hidden products', function(assert) {
|
|
assert.expect(1);
|
|
|
|
window.realtimeSearch.searchInput.value = 'cabbage';
|
|
window.realtimeSearch.filterProducts();
|
|
|
|
var productCards = document.querySelectorAll('.product-card');
|
|
var hiddenCards = Array.from(productCards).filter(function(card) {
|
|
return card.classList.contains('d-none');
|
|
});
|
|
|
|
assert.equal(hiddenCards.length, 3, '3 cards have d-none class');
|
|
});
|
|
|
|
QUnit.test('d-none class is removed from visible products', function(assert) {
|
|
assert.expect(2);
|
|
|
|
// First hide all
|
|
window.realtimeSearch.searchInput.value = 'xyz';
|
|
window.realtimeSearch.filterProducts();
|
|
|
|
var allHidden = Array.from(window.realtimeSearch.productCards).every(function(card) {
|
|
return card.classList.contains('d-none');
|
|
});
|
|
assert.ok(allHidden, 'all cards hidden initially');
|
|
|
|
// Then show all
|
|
window.realtimeSearch.searchInput.value = '';
|
|
window.realtimeSearch.filterProducts();
|
|
|
|
var allVisible = Array.from(window.realtimeSearch.productCards).every(function(card) {
|
|
return !card.classList.contains('d-none');
|
|
});
|
|
assert.ok(allVisible, 'all cards visible after clearing search');
|
|
});
|
|
|
|
QUnit.test('filterProducts returns correct counts', function(assert) {
|
|
assert.expect(4);
|
|
|
|
// All visible
|
|
window.realtimeSearch.searchInput.value = '';
|
|
var result1 = window.realtimeSearch.filterProducts();
|
|
assert.equal(result1.visible + result1.hidden, 4, 'total count is 4');
|
|
|
|
// 1 visible
|
|
window.realtimeSearch.searchInput.value = 'apple';
|
|
var result2 = window.realtimeSearch.filterProducts();
|
|
assert.equal(result2.visible, 1, 'visible count is 1');
|
|
|
|
// None visible
|
|
window.realtimeSearch.searchInput.value = 'xyz';
|
|
var result3 = window.realtimeSearch.filterProducts();
|
|
assert.equal(result3.visible, 0, 'visible count is 0');
|
|
|
|
// Category filter
|
|
window.realtimeSearch.searchInput.value = '';
|
|
window.realtimeSearch.categorySelect.value = '2';
|
|
var result4 = window.realtimeSearch.filterProducts();
|
|
assert.equal(result4.visible, 2, 'category filter shows 2 products');
|
|
});
|
|
});
|
|
|
|
return {};
|
|
});
|