u
This commit is contained in:
175
scripts/test-categoryproperty-and-attrvalue.js
Normal file
175
scripts/test-categoryproperty-and-attrvalue.js
Normal file
@@ -0,0 +1,175 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { mkdtempSync, rmSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import LibDashStore from '../src/index.js';
|
||||
import { BetterSqlite3Provider } from '../src/providers/sqlite3/index.js';
|
||||
|
||||
async function run() {
|
||||
console.log('--- Testing CategoryProperty & CategoryAttributeValue ---');
|
||||
|
||||
const tempDir = mkdtempSync(join(tmpdir(), 'test-cat-prop-attr-'));
|
||||
const dbFile = join(tempDir, 'test.db');
|
||||
const storageDir = join(tempDir, 'storage');
|
||||
|
||||
const provider = new BetterSqlite3Provider({
|
||||
filename: dbFile,
|
||||
storageDir,
|
||||
});
|
||||
|
||||
await provider.initialize();
|
||||
const store = await new LibDashStore(provider);
|
||||
|
||||
try {
|
||||
const googleAuthId = await store.google_auth.add('tester@example.com');
|
||||
const company = await store.company.create({
|
||||
name: 'Test Corp',
|
||||
iso639: 'de',
|
||||
taxrate: 19,
|
||||
reducedtaxrate: 7,
|
||||
googleAuthId,
|
||||
});
|
||||
await store.google_auth.setSelectedCompany(googleAuthId, company.id);
|
||||
|
||||
// Create a subcategory under root
|
||||
const category = await store.category.createUnderParent({
|
||||
googleAuthId,
|
||||
parentId: company.rootCategoryId,
|
||||
name: 'Test Category',
|
||||
});
|
||||
assert.ok(category.id > 0);
|
||||
|
||||
// 1. Test CategoryProperty
|
||||
console.log('1. Testing categoryproperty CRUD...');
|
||||
const prop1 = await store.propertyname.create(googleAuthId, {
|
||||
name: 'Material Care',
|
||||
exclusive: true,
|
||||
});
|
||||
const prop2 = await store.propertyname.create(googleAuthId, {
|
||||
name: 'Season',
|
||||
exclusive: false,
|
||||
});
|
||||
|
||||
// Set properties
|
||||
const setProps = await store.categoryproperty.setByCategoryId(googleAuthId, category.id, [
|
||||
{ propertyId: prop1.id, value: 'Dry Clean Only', sort: 10 },
|
||||
{ propertyId: prop2.id, value: 'Summer 2026', sort: 20 },
|
||||
]);
|
||||
assert.equal(setProps.length, 2);
|
||||
|
||||
// List properties
|
||||
const listedProps = await store.categoryproperty.listByCategoryId(googleAuthId, category.id);
|
||||
assert.equal(listedProps.length, 2);
|
||||
assert.equal(listedProps[0].name, 'Material Care');
|
||||
assert.equal(listedProps[0].value, 'Dry Clean Only');
|
||||
assert.equal(listedProps[0].exclusive, true);
|
||||
assert.equal(listedProps[1].name, 'Season');
|
||||
assert.equal(listedProps[1].value, 'Summer 2026');
|
||||
assert.equal(listedProps[1].exclusive, false);
|
||||
|
||||
// Test exclusive violation on categoryproperty
|
||||
await assert.rejects(
|
||||
async () => {
|
||||
await store.categoryproperty.setByCategoryId(googleAuthId, category.id, [
|
||||
{ propertyId: prop1.id, value: 'Val 1' },
|
||||
{ propertyId: prop1.id, value: 'Val 2' },
|
||||
]);
|
||||
},
|
||||
/exclusive/i,
|
||||
'Should reject multiple values for exclusive property'
|
||||
);
|
||||
|
||||
// Delete single property
|
||||
await store.categoryproperty.delete(googleAuthId, category.id, prop1.id);
|
||||
const afterDeleteProps = await store.categoryproperty.listByCategoryId(googleAuthId, category.id);
|
||||
assert.equal(afterDeleteProps.length, 1);
|
||||
assert.equal(afterDeleteProps[0].propertyId, prop2.id);
|
||||
|
||||
console.log('CategoryProperty tests passed!');
|
||||
|
||||
// 2. Test CategoryAttributeValue
|
||||
console.log('2. Testing categoryattributevalue CRUD...');
|
||||
const attrExclusive = await store.attributename.create(googleAuthId, {
|
||||
name: 'Department',
|
||||
exclusive: true,
|
||||
});
|
||||
const valDeptMen = await store.attributevalue.create(googleAuthId, attrExclusive.id, {
|
||||
value: 'Men',
|
||||
});
|
||||
const valDeptWomen = await store.attributevalue.create(googleAuthId, attrExclusive.id, {
|
||||
value: 'Women',
|
||||
});
|
||||
|
||||
const attrMulti = await store.attributename.create(googleAuthId, {
|
||||
name: 'Tags',
|
||||
exclusive: false,
|
||||
});
|
||||
const valTagSale = await store.attributevalue.create(googleAuthId, attrMulti.id, {
|
||||
value: 'Sale',
|
||||
});
|
||||
const valTagNew = await store.attributevalue.create(googleAuthId, attrMulti.id, {
|
||||
value: 'New',
|
||||
});
|
||||
|
||||
// Bulk set with numeric array
|
||||
const setAttrValues = await store.categoryattributevalue.setByCategoryId(googleAuthId, category.id, [
|
||||
valDeptMen.id,
|
||||
valTagSale.id,
|
||||
valTagNew.id,
|
||||
]);
|
||||
assert.equal(setAttrValues.length, 3);
|
||||
|
||||
// List attribute values
|
||||
const listedAttrValues = await store.categoryattributevalue.listByCategoryId(googleAuthId, category.id);
|
||||
assert.equal(listedAttrValues.length, 3);
|
||||
const deptMatch = listedAttrValues.find((v) => v.attributeName === 'Department');
|
||||
assert.ok(deptMatch);
|
||||
assert.equal(deptMatch.value, 'Men');
|
||||
assert.equal(deptMatch.exclusive, true);
|
||||
|
||||
// Test exclusive violation
|
||||
await assert.rejects(
|
||||
async () => {
|
||||
await store.categoryattributevalue.setByCategoryId(googleAuthId, category.id, [
|
||||
valDeptMen.id,
|
||||
valDeptWomen.id,
|
||||
]);
|
||||
},
|
||||
/exclusive/i,
|
||||
'Should reject multiple values for exclusive attribute'
|
||||
);
|
||||
|
||||
// Test flexible object shapes in setByCategoryId
|
||||
const setWithObjs = await store.categoryattributevalue.setByCategoryId(googleAuthId, category.id, [
|
||||
{ attributeValueId: valDeptWomen.id, sort: 5 },
|
||||
{ id: valTagSale.id, sort: 15 },
|
||||
]);
|
||||
assert.equal(setWithObjs.length, 2);
|
||||
const listedAfterObjSet = await store.categoryattributevalue.listByCategoryId(googleAuthId, category.id);
|
||||
assert.equal(listedAfterObjSet.length, 2);
|
||||
assert.equal(listedAfterObjSet[0].value, 'Women');
|
||||
assert.equal(listedAfterObjSet[0].sort, 5);
|
||||
|
||||
// 3. Test cascade deletion on category delete
|
||||
console.log('3. Testing cascade deletion when category is deleted...');
|
||||
await store.category.delete({ googleAuthId, id: category.id });
|
||||
|
||||
// Directly query database to ensure categoryproperty and categoryattributevalue rows were deleted by FK cascade
|
||||
const remainingProps = await provider.query('SELECT * FROM categoryproperty WHERE category_id = @id', { id: category.id });
|
||||
assert.equal(remainingProps.rows.length, 0);
|
||||
|
||||
const remainingAttrValues = await provider.query('SELECT * FROM categoryattributevalue WHERE category_id = @id', { id: category.id });
|
||||
assert.equal(remainingAttrValues.rows.length, 0);
|
||||
|
||||
console.log('All CategoryProperty and CategoryAttributeValue tests passed successfully!');
|
||||
} finally {
|
||||
try {
|
||||
rmSync(tempDir, { recursive: true, force: true });
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
|
||||
run().catch((err) => {
|
||||
console.error('Test failed:', err);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user