const assert = require('assert'); const axios = require('axios'); const dayjs = require('dayjs'); const openpgp = require('openpgp'); // Mock axios using a simple approach const mockAxios = (() => { const mocks = []; return { get: (url, config) => { const mock = mocks.find(m => m.method === 'get' && m.url === url); if (mock) return Promise.resolve(mock.response); return axios.get(url, config); // Fallback to real axios if no mock found }, post: (url, data, config) => { const mock = mocks.find(m => m.method === 'post' && m.url === url); if (mock) return Promise.resolve(mock.response); return axios.post(url, data, config); // Fallback to real axios if no mock found }, put: (url, data, config) => { const mock = mocks.find(m => m.method === 'put' && m.url === url); if (mock) return Promise.resolve(mock.response); return axios.put(url, data, config); // Fallback to real axios if no mock found }, delete: (url, config) => { const mock = mocks.find(m => m.method === 'delete' && m.url === url); if (mock) return Promise.resolve(mock.response); return axios.delete(url, config); // Fallback to real axios if no mock found }, mock: (method, url, response) => { mocks.push({ method, url, response }); }, clear: () => { mocks.length = 0; } }; })(); // apx.js functions implemented within the test file const apx = {}; apx.generateKey = async (alias, passphrase) => { const pgpParams = { type: 'ecc', curve: 'curve25519', userIDs: [{ name: alias }], passphrase: passphrase, format: 'armored' }; const key = await openpgp.generateKey(pgpParams); return { alias, privatekey: key.privateKeyArmored, publickey: key.publicKeyArmored }; }; apx.createIdentity = async (alias, passphrase) => { try { const { privatekey, publickey } = await apx.generateKey(alias, passphrase); const response = await axios.post('/api/adminapi/pagans', { alias, publickey }); return response.data; } catch (error) { console.error('Error creating identity:', error); } }; apx.clearmsgSignature = async (privateKeyArmored, passphrase, message) => { const { keys: [privateKey] } = await openpgp.decryptKey({ privateKey: await openpgp.readKey({ armoredKey: privateKeyArmored }), passphrase }); const signedMessage = await openpgp.sign({ message: await openpgp.createMessage({ text: message }), signingKeys: privateKey }); return signedMessage; }; apx.jointribe = async (headers) => { try { const response = await axios.put(`/api/adminapi/pagans/person/${headers.xtribe}`, { headers }); return response.data; } catch (error) { console.error('Error joining tribe:', error); } }; apx.deleteIdentity = async (headers, alias) => { try { const response = await axios.delete(`/api/adminapi/pagans/person/${headers.xtribe}/${alias}`, { headers }); return response.data; } catch (error) { console.error('Error deleting identity:', error); } }; const headers = { xtrkversion: 1, xalias: 'anonymous', xapp: 'smatchapp', xdays: 0, xhash: 'anonymous', xlang: 'fr', xprofils: 'anonymous', xtribe: 'smatchit', xuuid: '0' }; let alias = 'testalias'; let passphrase = 'testpassphrase'; let privateKey, publicKey; let authHeaders; const testCases = [ { name: 'Create Identity', async run() { const keys = await apx.generateKey(alias, passphrase); privateKey = keys.privatekey; publicKey = keys.publickey; mockAxios.mock('get', `/api/adminapi/pagans/alias/${alias}`, { status: 404 }); mockAxios.mock('post', '/api/adminapi/pagans', { data: { status: 200, ref: 'Pagans', msg: 'identitycreated', data: { alias } } }); await apx.createIdentity(alias, passphrase); }, async verify() { const response = await mockAxios.get(`/api/adminapi/pagans/alias/${alias}`); assert.strictEqual(response.status, 200, 'Alias should exist after creation'); assert.strictEqual(response.data.alias, alias, 'Alias data should match'); } }, { name: 'Authenticate', async run() { headers.xalias = alias; headers.xdays = dayjs().valueOf(); const msg = `${alias}_${headers.xdays}`; headers.xhash = await apx.clearmsgSignature(privateKey, passphrase, msg); mockAxios.mock('get', '/api/adminapi/pagans/isauth', { data: { data: { xprofils: ['pagans', 'persons'] } } }); authHeaders = { ...headers, xhash: headers.xhash, xdays: headers.xdays }; await mockAxios.get('/api/adminapi/pagans/isauth', { headers: authHeaders }); }, verify() { // Assertions can be added here if needed } }, { name: 'Join Tribe', async run() { mockAxios.mock('put', `/api/adminapi/pagans/person/${headers.xtribe}`, { status: 200 }); await apx.jointribe(authHeaders); }, verify() { // Assertions can be added here if needed } }, { name: 'Modify First Name', async run() { const newFirstName = 'NewFirstName'; mockAxios.mock('put', `/api/adminapi/pagans/person/${headers.xtribe}`, { status: 200, data: { alias, firstName: newFirstName } }); await mockAxios.put(`/api/adminapi/pagans/person/${headers.xtribe}`, { alias, addprofil: 'newprofil', persontochange: alias }, { headers: authHeaders }); }, async verify() { const response = await mockAxios.get(`/api/adminapi/pagans/person/${headers.xtribe}/${alias}`, { headers: authHeaders }); assert.strictEqual(response.data.firstName, 'NewFirstName', 'First name should be updated'); } }, { name: 'Revert First Name', async run() { const originalFirstName = 'OriginalFirstName'; mockAxios.mock('put', `/api/adminapi/pagans/person/${headers.xtribe}`, { status: 200, data: { alias, firstName: originalFirstName } }); await mockAxios.put(`/api/adminapi/pagans/person/${headers.xtribe}`, { alias, addprofil: 'newprofil', persontochange: alias }, { headers: authHeaders }); }, async verify() { const response = await mockAxios.get(`/api/adminapi/pagans/person/${headers.xtribe}/${alias}`, { headers: authHeaders }); assert.strictEqual(response.data.firstName, 'OriginalFirstName', 'First name should be reverted'); } }, { name: 'Delete Identity', async run() { mockAxios.mock('delete', `/api/adminapi/pagans/person/${headers.xtribe}/${alias}`, { status: 200 }); await apx.deleteIdentity(authHeaders, alias); }, async verify() { const response = await mockAxios.get(`/api/adminapi/pagans/alias/${alias}`); assert.strictEqual(response.status, 404, 'Alias should not exist after deletion'); } } ]; const runTests = async () => { for (const testCase of testCases) { console.log(`Running test case: ${testCase.name}`); await testCase.run(); await testCase.verify(); mockAxios.clear(); // Clear mocks between tests } }; runTests().then(() => { console.log('All test cases ran successfully'); }).catch(err => { console.error('Test case failed:', err); });