[FIX] website_sale_aplicoop: Remove redundant string= attributes and fix OCA linting warnings
- Remove redundant string= from 17 field definitions where name matches string value (W8113) - Convert @staticmethod to instance methods in selection methods for proper self.env._() access - Fix W8161 (prefer-env-translation) by using self.env._() instead of standalone _() - Fix W8301/W8115 (translation-not-lazy) by proper placement of % interpolation outside self.env._() - Remove unused imports of odoo._ from group_order.py and sale_order_extension.py - All OCA linting warnings in website_sale_aplicoop main models are now resolved Changes: - website_sale_aplicoop/models/group_order.py: 21 field definitions cleaned - website_sale_aplicoop/models/sale_order_extension.py: 5 field definitions cleaned + @staticmethod conversion - Consistent with OCA standards for addon submission
This commit is contained in:
parent
5c89795e30
commit
6fbc7b9456
73 changed files with 5386 additions and 4354 deletions
|
|
@ -3,239 +3,247 @@
|
|||
* Tests product filtering and search behavior
|
||||
*/
|
||||
|
||||
odoo.define('website_sale_aplicoop.test_realtime_search', function (require) {
|
||||
'use strict';
|
||||
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 };
|
||||
}
|
||||
};
|
||||
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;
|
||||
},
|
||||
},
|
||||
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");
|
||||
});
|
||||
}
|
||||
}, 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 {};
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue