test: unit-test get-launch-apps

This commit is contained in:
KernelDeimos
2024-12-20 12:26:48 -05:00
parent c6c3844763
commit 3da571c39a
5 changed files with 207 additions and 6 deletions

36
package-lock.json generated
View File

@@ -10500,6 +10500,18 @@
"resolved": "tools/file-walker",
"link": true
},
"node_modules/fill-keys": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz",
"integrity": "sha512-tcgI872xXjwFF4xgQmLxi76GnwJG3g/3isB1l4/G5Z4zrbddGpBjqZCO9oEAcB5wX0Hj/5iQB3toxfO7in1hHA==",
"dependencies": {
"is-object": "~1.0.1",
"merge-descriptors": "~1.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -11884,6 +11896,14 @@
"node": ">=0.12.0"
}
},
"node_modules/is-object": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz",
"integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-path-inside": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
@@ -13408,6 +13428,11 @@
"resolved": "tools/module-docgen",
"link": true
},
"node_modules/module-not-found-error": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz",
"integrity": "sha512-pEk4ECWQXV6z2zjhRZUongnLJNUeGQJ3w6OQ5ctGwD+i5o93qjRQUk2Rt6VdNeu3sEP0AB4LcfvdebpxBRVr4g=="
},
"node_modules/moment": {
"version": "2.30.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
@@ -14730,6 +14755,16 @@
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"license": "MIT"
},
"node_modules/proxyquire": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-2.1.3.tgz",
"integrity": "sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg==",
"dependencies": {
"fill-keys": "^1.0.2",
"module-not-found-error": "^1.0.1",
"resolve": "^1.11.1"
}
},
"node_modules/pstree.remy": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
@@ -17712,6 +17747,7 @@
"openai": "^4.73.1",
"otpauth": "9.2.4",
"prompt-sync": "^4.2.0",
"proxyquire": "^2.1.3",
"recursive-readdir": "^2.2.3",
"response-time": "^2.3.2",
"seedrandom": "^3.0.5",

View File

@@ -4,7 +4,7 @@
"description": "Backend/Kernel for Puter",
"main": "exports.js",
"scripts": {
"test": "npx mocha"
"test": "npx mocha src/**/*.test.js && node ./tools/test.js"
},
"dependencies": {
"@anthropic-ai/sdk": "^0.26.1",
@@ -61,6 +61,7 @@
"openai": "^4.73.1",
"otpauth": "9.2.4",
"prompt-sync": "^4.2.0",
"proxyquire": "^2.1.3",
"recursive-readdir": "^2.2.3",
"response-time": "^2.3.2",
"seedrandom": "^3.0.5",

View File

@@ -26,7 +26,7 @@ const { DB_READ } = require('../services/database/consts.js');
// -----------------------------------------------------------------------//
// GET /get-launch-apps
// -----------------------------------------------------------------------//
router.get('/get-launch-apps', auth, express.json(), async (req, res, next)=>{
module.exports = async (req, res) => {
let result = {};
// -----------------------------------------------------------------------//
@@ -118,6 +118,4 @@ router.get('/get-launch-apps', auth, express.json(), async (req, res, next)=>{
}
return res.send(result);
})
module.exports = router
};

View File

@@ -0,0 +1,156 @@
const sinon = require('sinon');
const { expect } = require('chai');
const proxyquire = require('proxyquire');
const kvjs = require('@heyputer/kv.js');
const uuid = require('uuid');
const TEST_UUID_NAMESPACE = '5568ab95-229d-4d87-b98c-0b12680a9524';
const apps_names_expected_to_exist = [
'app-center',
'dev-center',
'editor',
];
const data_mockapps = (() => {
const data_mockapps = [];
// List of app names that get-launch-apps expects to exist
for ( const name of apps_names_expected_to_exist ) {
data_mockapps.push({
uid: 'app-' + uuid.v5(name, TEST_UUID_NAMESPACE),
name,
title: 'App Name',
icon: 'icon-goes-here',
godmode: false,
maximize_on_start: false,
index_url: 'index-url'
});
}
// An additional app that won't show up in taskbar
data_mockapps.push({
uid: 'app-' + uuid.v5('hidden-app', TEST_UUID_NAMESPACE),
name: 'hidden-app',
title: 'Hidden App',
icon: 'icon-goes-here',
godmode: false,
maximize_on_start: false,
index_url: 'index-url'
});
// An additional app tha only shows up in recents
data_mockapps.push({
uid: 'app-' + uuid.v5('recent-app', TEST_UUID_NAMESPACE),
name: 'recent-app',
title: 'Recent App',
icon: 'icon-goes-here',
godmode: false,
maximize_on_start: false,
index_url: 'index-url'
});
return data_mockapps;
})();
const data_appopens = [
{
app_uid: 'app-' + uuid.v5('app-center', TEST_UUID_NAMESPACE),
},
{
app_uid: 'app-' + uuid.v5('editor', TEST_UUID_NAMESPACE),
},
{
app_uid: 'app-' + uuid.v5('recent-app', TEST_UUID_NAMESPACE),
},
];
describe('GET /launch-apps', () => {
it('should return expected format', async () => {
globalThis.kv = new kvjs();
const database_mock = {
read: async (query) => {
if ( query.includes('FROM app_opens') ) {
return data_appopens;
}
}
};
const services_mock = {
get: (key) => {
if (key === 'database') {
return {
get: () => database_mock,
}
}
}
};
const req_mock = {
user: {
id: 1 + Math.floor(Math.random() * 1000**3),
},
services: services_mock,
send: sinon.spy(),
};
const res_mock = {
send: sinon.spy(),
};
const get_launch_apps = proxyquire('./get-launch-apps', {
'../helpers.js': {
get_app: async ({ uid, name }) => {
if ( uid ) {
return data_mockapps.find(app => app.uid === uid);
}
if ( name ) {
return data_mockapps.find(app => app.name === name);
}
}
}
});
await get_launch_apps(req_mock, res_mock);
expect(res_mock.send.calledOnce).to.equal(true, 'res.send should be called once');
const call = res_mock.send.firstCall;
response = call.args[0];
console.log('response', response);
expect(response).to.be.an('object');
expect(response).to.have.property('recommended');
expect(response.recommended).to.be.an('array');
expect(response.recommended).to.have.lengthOf(apps_names_expected_to_exist.length);
expect(response.recommended).to.deep.equal(
data_mockapps
.filter(app => apps_names_expected_to_exist.includes(app.name))
.map(app => ({
uuid: app.uid,
name: app.name,
title: app.title,
icon: app.icon,
godmode: app.godmode,
maximize_on_start: app.maximize_on_start,
index_url: app.index_url,
}))
);
expect(response).to.have.property('recent');
expect(response.recent).to.be.an('array');
expect(response.recent).to.have.lengthOf(data_appopens.length);
expect(response.recent).to.deep.equal(
data_mockapps
.filter(app => data_appopens.map(app_open => app_open.app_uid).includes(app.uid))
.map(app => ({
uuid: app.uid,
name: app.name,
title: app.title,
icon: app.icon,
godmode: app.godmode,
maximize_on_start: app.maximize_on_start,
index_url: app.index_url,
}))
);
})
});

View File

@@ -17,6 +17,8 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const configurable_auth = require("../middleware/configurable_auth");
const { Endpoint } = require("../util/expressutil");
const BaseService = require("./BaseService");
@@ -64,7 +66,7 @@ class PuterAPIService extends BaseService {
app.use(require('../routers/kvstore/setItem'))
app.use(require('../routers/kvstore/listItems'))
app.use(require('../routers/kvstore/clearItems'))
app.use(require('../routers/get-launch-apps'))
// app.use(require('../routers/get-launch-apps'))
app.use(require('../routers/itemMetadata'))
app.use(require('../routers/login'))
app.use(require('../routers/logout'))
@@ -91,6 +93,14 @@ class PuterAPIService extends BaseService {
app.use(require('../routers/update-taskbar-items'))
require('../routers/whoami')(app);
Endpoint({
route: '/get-launch-apps',
methods: ['GET'],
mw: [configurable_auth()],
handler: require('../routers/get-launch-apps'),
}).attach(app);
}
}