'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); });