| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
- import test from 'node:test';
- import assert from 'node:assert/strict';
- import { readFileSync } from 'node:fs';
- import { runInNewContext } from 'node:vm';
- const source = readFileSync(new URL('../deploy-admin-functions.mjs', import.meta.url), 'utf8');
- const gateway = source.slice(source.indexOf('async function queryUsers(context,input)'));
- function functionSource(name) {
- const start = gateway.search(new RegExp(`^(?:async )?function ${name}\\(`, 'm'));
- assert.ok(start >= 0, `Missing ${name}`);
- const rest = gateway.slice(start);
- const end = rest.slice(1).search(/^(?:async )?function /m);
- return end < 0 ? rest : rest.slice(0, end + 1);
- }
- for (const live of [false, true]) {
- test(`门店在学正常人数复用会员筛选,按归属汇总且不受门店分页影响(旧门店数据:${live})`, async () => {
- const member = (userId, parentUserId, learningStatus, status) => ({ userId, parentUserId, learningStatus, status });
- const members = [
- member(101, 1, 'studying', 'active'), member(102, 1, 'studying', 'active'),
- member(103, 1, 'studying', 'disabled'), member(104, 1, 'completed', 'active'),
- member(105, 1, 'trial', 'active'), member(106, 1, 'not_started', 'active'),
- member(201, 2, 'studying', 'active'), member(202, 2, 'completed', 'active'),
- member(401, 4, 'studying', 'active'), member(901, 0, 'studying', 'active'),
- ];
- const stores = [1, 2, 3].map((id) => ({ objectId: `store-${id}`, legacyUserId: id, username: `门店${id}` }));
- const context = {
- number: (value, fallback = 0) => Number(value) || fallback,
- text: (value) => String(value ?? ''),
- companyIdOf: () => 'company', roleOf: () => 'ops-manager',
- legacyOf: (row) => row.legacyUserData || {}, mobileOf: () => '', maskMobile: () => '',
- registeredAtOf: () => '', firstDateIso: () => '', dateIso: () => '', businessDate: () => '2026-09-25',
- Psql: { query: async (sql) => sql.startsWith('SELECT u.*') ? stores : [] },
- coachRows: async () => [], appointmentSnapshot: async () => ({ appointments: [], live: {} }),
- optionalLegacyMemberSnapshot: async () => ({ available: live, coachIds: [], items: live ? [{ userId: 4, groupId: 2, username: '旧门店4' }] : [] }),
- queryUsers: async () => members, operationalSyncIndicator: async () => ({}),
- searchRows: (rows) => rows,
- };
- runInNewContext(['pageInput', 'pageRows', 'filterMembers', 'storeNameOf', 'storeMobileOf', 'storeRows'].map(functionSource).join('\n') + '\nthis.listStores = storeRows;', context);
- const result = await context.listStores({}, { page: 1, pageSize: 20 });
- const byId = new Map(result.items.map((row) => [row.userId, row]));
- assert.equal(byId.get(1).memberCount, 6);
- assert.equal(byId.get(1).activeStudyingMemberCount, 2);
- assert.equal(byId.get(2).activeStudyingMemberCount, 1);
- assert.equal(byId.get(3).activeStudyingMemberCount, 0);
- if (live) assert.equal(byId.get(4).activeStudyingMemberCount, 1);
- for (const row of result.items) {
- const expected = context.filterMembers(members, { filters: { parentUserId: row.userId, status: 'active', learningStatus: 'studying' } }).length;
- assert.equal(row.activeStudyingMemberCount, expected);
- }
- const paged = await context.listStores({}, { page: 2, pageSize: 1 });
- assert.equal(paged.items.length, 1);
- assert.equal(paged.items[0].activeStudyingMemberCount, byId.get(paged.items[0].userId).activeStudyingMemberCount);
- });
- }
|