cangku/backend/test/alibaba1688ImageSearchSettings.test.js

97 lines
3.2 KiB
JavaScript

'use strict';
const assert = require('node:assert/strict');
const crypto = require('node:crypto');
const test = require('node:test');
const {
CREDENTIAL_VALIDITY_MS,
DEFAULT_ENDPOINT_URL,
buildAlibaba1688SignedHeaders,
extractAkKeys,
getAlibaba1688GatewayError,
getCredentialValidity,
stripSecretFields,
} = require('../src/services/alibaba1688ImageSearchSettings');
test('extractAkKeys decodes the dedicated 1688 credential format', () => {
const secret = 's'.repeat(32);
const akId = 'dedicated-1688-access-id';
const encoded = Buffer.from(`${secret}${akId}`, 'utf8').toString('base64url');
assert.deepEqual(extractAkKeys(encoded), { secret, akId });
});
test('buildAlibaba1688SignedHeaders creates the required gateway headers', () => {
const secret = 'x'.repeat(32);
const akId = 'image-search-access-id';
const ak = Buffer.from(`${secret}${akId}`, 'utf8').toString('base64url');
const body = JSON.stringify({ imageUrl: 'https://example.com/product.jpg', pageSize: 10 });
const headers = buildAlibaba1688SignedHeaders({
method: 'POST',
uri: '/api/find_product/1.0.0',
body,
ak,
});
assert.equal(headers['Content-Type'], 'application/json');
assert.equal(headers['x-csk-ak'], akId);
assert.equal(headers['x-csk-version'], '1.7.0');
assert.equal(headers['x-csk-content-md5'], crypto.createHash('md5').update(body, 'utf8').digest('base64'));
assert.match(headers['x-csk-time'], /^\d+$/);
assert.match(headers['x-csk-nonce'], /^[a-f0-9]{8}$/);
assert.ok(headers['x-csk-sign']);
});
test('legacy 1688 secrets are removed from general configuration', () => {
assert.deepEqual(stripSecretFields({
endpointUrl: DEFAULT_ENDPOINT_URL,
timeoutMs: 45000,
ak: 'legacy-ak',
apiKey: 'legacy-api-key',
api_key: 'legacy-api-key-2',
}), {
endpointUrl: DEFAULT_ENDPOINT_URL,
timeoutMs: 45000,
});
});
test('1688 gateway business responses reject disabled credentials', () => {
assert.equal(getAlibaba1688GatewayError({
success: false,
code: 'AccessKeyDisabled',
msgInfo: 'AccessKey已被禁用',
httpCode: 200,
}), 'AccessKey已被禁用');
assert.equal(getAlibaba1688GatewayError({
success: true,
code: 'SUCCESS',
msgInfo: '成功',
httpCode: 200,
}), '');
});
test('tracked 1688 credentials expose a seven-day countdown without rounding away time', () => {
const now = Date.parse('2026-09-11T01:00:00.000Z');
const validity = getCredentialValidity({
ak: 'configured-ak',
credentialUpdatedAt: new Date(now).toISOString(),
credentialExpiresAt: new Date(now + CREDENTIAL_VALIDITY_MS).toISOString(),
}, now);
assert.equal(validity.status, 'active');
assert.equal(validity.tracked, true);
assert.equal(validity.validityDays, 7);
assert.equal(validity.remainingDays, 7);
assert.equal(validity.percentRemaining, 100);
});
test('legacy 1688 credentials remain explicitly untracked instead of inventing an expiry date', () => {
const validity = getCredentialValidity({ ak: 'legacy-ak' }, Date.parse('2026-09-11T01:00:00.000Z'));
assert.equal(validity.status, 'untracked');
assert.equal(validity.tracked, false);
assert.equal(validity.expiresAt, null);
assert.equal(validity.remainingDays, null);
});