Align homepage and category discovery, modern widgets, admin controls, quotes, and comments with the reference theme. Remove superseded paths and add rendering and behavior coverage. Update stale asset and finance contracts; all 760 Node tests and 139 widget assertions pass.
140 lines
4.4 KiB
JavaScript
140 lines
4.4 KiB
JavaScript
'use strict';
|
|
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const vm = require('node:vm');
|
|
const test = require('node:test');
|
|
|
|
const root = path.resolve(__dirname, '..', '..');
|
|
|
|
class Element {
|
|
constructor(tag = 'div') {
|
|
this.tagName = tag.toUpperCase();
|
|
this.children = [];
|
|
this.dataset = {};
|
|
this.attributes = {};
|
|
this.disabled = false;
|
|
this.hidden = false;
|
|
this.listeners = {};
|
|
this._textContent = '';
|
|
this.className = '';
|
|
this.classList = {
|
|
values: new Set(),
|
|
add: (...values) => values.forEach((value) => this.classList.values.add(value)),
|
|
};
|
|
}
|
|
|
|
set textContent(value) {
|
|
this._textContent = String(value);
|
|
this.children = [];
|
|
}
|
|
|
|
get textContent() {
|
|
return this._textContent + this.children.map((child) => child.textContent || '').join('');
|
|
}
|
|
|
|
appendChild(child) {
|
|
this.children.push(child);
|
|
return child;
|
|
}
|
|
|
|
addEventListener(type, callback) {
|
|
this.listeners[type] = callback;
|
|
}
|
|
|
|
setAttribute(name, value) {
|
|
this.attributes[name] = String(value);
|
|
}
|
|
|
|
closest(selector) {
|
|
return selector === '[data-aksrt-withdraw-history-page]' && this.dataset.aksrtWithdrawHistoryPage
|
|
? this
|
|
: null;
|
|
}
|
|
}
|
|
|
|
function textContent(node) {
|
|
return node.textContent;
|
|
}
|
|
|
|
test('withdrawal history requests paged ten-item results and renders the returned page', async () => {
|
|
const requests = [];
|
|
const pagePayloads = {
|
|
1: {
|
|
items: [{ status: 'completed', gross_amount: '10.00', amount: '9.50', withdrawal_number: 'W1', created_at: '2026-10-01', note: 'private note' }],
|
|
page: 1,
|
|
max_pages: 2,
|
|
},
|
|
2: {
|
|
items: [{ status: 'pending', gross_amount: '20.00', amount: '20.00', withdrawal_number: 'W2', created_at: '2026-10-02' }],
|
|
page: 2,
|
|
max_pages: 2,
|
|
},
|
|
};
|
|
const list = new Element();
|
|
const pagination = new Element('nav');
|
|
const closeButtons = [];
|
|
const modal = new Element();
|
|
modal.querySelector = (selector) => selector === '[data-aksrt-withdraw-history-list]' ? list : pagination;
|
|
modal.querySelectorAll = () => closeButtons;
|
|
const openButton = new Element('button');
|
|
const document = {
|
|
body: { classList: { add() {}, remove() {} } },
|
|
querySelector: (selector) => selector === '[data-aksrt-withdraw-history-modal]' ? modal : null,
|
|
querySelectorAll: (selector) => selector === '[data-aksrt-withdraw-history-open]' ? [openButton] : [],
|
|
createElement: (tag) => new Element(tag),
|
|
createTextNode: (text) => ({ textContent: String(text) }),
|
|
};
|
|
let init;
|
|
const jQuery = () => ({
|
|
off() { return this; },
|
|
on(_event, callback) { init = callback; return this; },
|
|
});
|
|
const fetch = (url) => {
|
|
requests.push(url);
|
|
const page = Number(new URL(url).searchParams.get('page'));
|
|
return Promise.resolve({
|
|
ok: true,
|
|
json: () => Promise.resolve(pagePayloads[page]),
|
|
});
|
|
};
|
|
const source = fs.readFileSync(path.join(root, 'assets/js/credits-withdraw-history.js'), 'utf8');
|
|
|
|
vm.runInNewContext(source, {
|
|
window: { aksrtData: { restUrl: 'https://example.test/wp-json/aksrt/v1', restNonce: 'nonce' } },
|
|
document,
|
|
jQuery,
|
|
fetch,
|
|
Array,
|
|
Number,
|
|
String,
|
|
Math,
|
|
parseInt,
|
|
Promise,
|
|
Error,
|
|
});
|
|
|
|
assert.equal(typeof init, 'function', 'module registers its lifecycle initializer');
|
|
init();
|
|
openButton.listeners.click({ preventDefault() {} });
|
|
await new Promise((resolve) => setImmediate(resolve));
|
|
|
|
assert.equal(requests.length, 1);
|
|
assert.equal(new URL(requests[0]).pathname, '/wp-json/aksrt/v1/earnings/withdrawals');
|
|
assert.equal(new URL(requests[0]).searchParams.get('page'), '1');
|
|
assert.equal(new URL(requests[0]).searchParams.get('per_page'), '10');
|
|
assert.match(textContent(list.children[0]), /实际到账:9\.50元/);
|
|
assert.doesNotMatch(textContent(list.children[0]), /private note/);
|
|
|
|
const pageTwo = pagination.children.find((button) => button.dataset.aksrtWithdrawHistoryPage === '2');
|
|
assert.ok(pageTwo, 'the API max_pages value creates a second-page control');
|
|
pagination.listeners.click({ target: pageTwo, preventDefault() {} });
|
|
await new Promise((resolve) => setImmediate(resolve));
|
|
|
|
assert.equal(requests.length, 2);
|
|
assert.equal(new URL(requests[1]).searchParams.get('page'), '2');
|
|
assert.equal(new URL(requests[1]).searchParams.get('per_page'), '10');
|
|
assert.match(textContent(list.children[0]), /W2/);
|
|
});
|