68 lines
3.2 KiB
JavaScript
68 lines
3.2 KiB
JavaScript
import './setup.mjs';
|
|
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import { adminUserId, load } from './setup.mjs';
|
|
|
|
const owner = adminUserId();
|
|
const { createPsadtProfile, renderPsadtProfile } = await load('../models/psadtModel.js');
|
|
const { createAssetFromUpload, createAssetLink, listLinkedAssets } = await load('../models/assetModel.js');
|
|
const { buildZip, planPackageLayout } = await load('../services/packageBuilder.js');
|
|
|
|
function seedAsset(name, contents) {
|
|
const tmp = path.join(os.tmpdir(), `pkg-src-${Math.random().toString(16).slice(2)}`);
|
|
fs.writeFileSync(tmp, contents);
|
|
return createAssetFromUpload(
|
|
{ path: tmp, originalname: name, mimetype: 'application/octet-stream', size: contents.length },
|
|
{ name, visibility: 'shared' },
|
|
owner
|
|
);
|
|
}
|
|
|
|
test('listLinkedAssets returns a PSADT profile\'s linked assets with their package path and role', () => {
|
|
const profile = createPsadtProfile({ name: 'Linked Pkg App', appVendor: 'Acme', appName: 'Tool', visibility: 'shared' }, owner);
|
|
const installer = seedAsset('setup.exe', Buffer.from('MZ binary'));
|
|
createAssetLink(installer.id, { targetType: 'psadt_profile', targetId: profile.id, linkRole: 'installer', packagePath: 'Files/setup.exe' }, owner);
|
|
|
|
const linked = listLinkedAssets('psadt_profile', profile.id, owner);
|
|
assert.equal(linked.length, 1);
|
|
assert.equal(linked[0].assetId, installer.id);
|
|
assert.equal(linked[0].linkRole, 'installer');
|
|
assert.equal(linked[0].packagePath, 'Files/setup.exe');
|
|
});
|
|
|
|
test('a profile + linked assets assemble into a zip carrying the rendered script and payload', () => {
|
|
const profile = createPsadtProfile({ name: 'Assemble App', appVendor: 'Acme', appName: 'Assemble', visibility: 'shared' }, owner);
|
|
const installer = seedAsset('install.exe', Buffer.from('payload-bytes'));
|
|
const config = seedAsset('settings.xml', Buffer.from('<config/>'));
|
|
createAssetLink(installer.id, { targetType: 'psadt_profile', targetId: profile.id, linkRole: 'installer' }, owner);
|
|
createAssetLink(config.id, { targetType: 'psadt_profile', targetId: profile.id, linkRole: 'support-file' }, owner);
|
|
|
|
const rendered = renderPsadtProfile(profile.id, owner);
|
|
const layout = planPackageLayout(listLinkedAssets('psadt_profile', profile.id, owner));
|
|
assert.deepEqual(layout.assets.map((a) => a.packagePath).sort(), ['Files/install.exe', 'SupportFiles/settings.xml']);
|
|
|
|
const zip = buildZip([
|
|
{ path: 'Invoke-AppDeployToolkit.ps1', data: Buffer.from(rendered.script, 'utf8') },
|
|
{ path: 'Files/install.exe', data: Buffer.from('payload-bytes') }
|
|
]);
|
|
const names = listZipNames(zip);
|
|
assert.ok(names.includes('Invoke-AppDeployToolkit.ps1'));
|
|
assert.ok(names.includes('Files/install.exe'));
|
|
});
|
|
|
|
function listZipNames(buf) {
|
|
const names = [];
|
|
let pos = 0;
|
|
while (buf.readUInt32LE(pos) === 0x04034b50) {
|
|
const compSize = buf.readUInt32LE(pos + 18);
|
|
const nameLen = buf.readUInt16LE(pos + 26);
|
|
const extraLen = buf.readUInt16LE(pos + 28);
|
|
names.push(buf.slice(pos + 30, pos + 30 + nameLen).toString('utf8'));
|
|
pos = pos + 30 + nameLen + extraLen + compSize;
|
|
}
|
|
return names;
|
|
}
|