mirror of
https://github.com/HeyPuter/puter.git
synced 2026-05-15 05:51:15 +00:00
perf: optimize recommended apps
This commit is contained in:
@@ -32,48 +32,53 @@ module.exports = async (req, res) => {
|
||||
// -----------------------------------------------------------------------//
|
||||
// Recommended apps
|
||||
// -----------------------------------------------------------------------//
|
||||
let app_names = new Set([
|
||||
'app-center',
|
||||
'dev-center',
|
||||
'editor',
|
||||
'code',
|
||||
'terminal',
|
||||
'draw',
|
||||
'silex',
|
||||
'camera',
|
||||
'recorder',
|
||||
'shell-shockers-outpan',
|
||||
'krunker',
|
||||
'slash-frvr',
|
||||
'viewer',
|
||||
'solitaire-frvr',
|
||||
'markus',
|
||||
'player',
|
||||
'pdf',
|
||||
'polotno',
|
||||
'basketball-frvr',
|
||||
'gold-digger-frvr',
|
||||
'plushie-connect',
|
||||
'hex-frvr',
|
||||
'spider-solitaire',
|
||||
]);
|
||||
result.recommended = kv.get('global:recommended-apps');
|
||||
if ( ! result.recommended ) {
|
||||
let app_names = new Set([
|
||||
'app-center',
|
||||
'dev-center',
|
||||
'editor',
|
||||
'code',
|
||||
'terminal',
|
||||
'draw',
|
||||
'silex',
|
||||
'camera',
|
||||
'recorder',
|
||||
'shell-shockers-outpan',
|
||||
'krunker',
|
||||
'slash-frvr',
|
||||
'viewer',
|
||||
'solitaire-frvr',
|
||||
'markus',
|
||||
'player',
|
||||
'pdf',
|
||||
'polotno',
|
||||
'basketball-frvr',
|
||||
'gold-digger-frvr',
|
||||
'plushie-connect',
|
||||
'hex-frvr',
|
||||
'spider-solitaire',
|
||||
]);
|
||||
|
||||
// Prepare each app for returning to user by only returning the necessary fields
|
||||
// and adding them to the retobj array
|
||||
result.recommended = [];
|
||||
for ( const name of app_names ) {
|
||||
const app = await get_app({ name });
|
||||
if ( ! app ) continue;
|
||||
// Prepare each app for returning to user by only returning the necessary fields
|
||||
// and adding them to the retobj array
|
||||
result.recommended = [];
|
||||
for ( const name of app_names ) {
|
||||
const app = await get_app({ name });
|
||||
if ( ! app ) continue;
|
||||
|
||||
result.recommended.push({
|
||||
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,
|
||||
});
|
||||
result.recommended.push({
|
||||
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,
|
||||
});
|
||||
}
|
||||
|
||||
kv.set('global:recommended-apps', result.recommended);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------//
|
||||
|
||||
@@ -64,93 +64,164 @@ const data_appopens = [
|
||||
},
|
||||
];
|
||||
|
||||
const get_mock_context = () => {
|
||||
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_app = sinon.spy(async ({ uid, name }) => {
|
||||
if ( uid ) {
|
||||
return data_mockapps.find(app => app.uid === uid);
|
||||
}
|
||||
if ( name ) {
|
||||
return data_mockapps.find(app => app.name === name);
|
||||
}
|
||||
});
|
||||
|
||||
const get_launch_apps = proxyquire('./get-launch-apps', {
|
||||
'../helpers.js': {
|
||||
get_app,
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
get_launch_apps, req_mock, res_mock,
|
||||
spies: {
|
||||
get_app,
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
describe('GET /launch-apps', () => {
|
||||
globalThis.kv = new kvjs();
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
// First call
|
||||
{
|
||||
const { get_launch_apps, req_mock, res_mock, spies } = get_mock_context();
|
||||
await get_launch_apps(req_mock, res_mock);
|
||||
|
||||
const req_mock = {
|
||||
user: {
|
||||
id: 1 + Math.floor(Math.random() * 1000**3),
|
||||
},
|
||||
services: services_mock,
|
||||
send: sinon.spy(),
|
||||
};
|
||||
expect(res_mock.send.calledOnce).to.equal(true, 'res.send should be called once');
|
||||
|
||||
const res_mock = {
|
||||
send: sinon.spy(),
|
||||
};
|
||||
const call = res_mock.send.firstCall;
|
||||
response = call.args[0];
|
||||
console.log('response', response);
|
||||
|
||||
expect(response).to.be.an('object');
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
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,
|
||||
}))
|
||||
);
|
||||
|
||||
await get_launch_apps(req_mock, res_mock);
|
||||
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,
|
||||
}))
|
||||
);
|
||||
|
||||
expect(res_mock.send.calledOnce).to.equal(true, 'res.send should be called once');
|
||||
// << HOW TO FIX >>
|
||||
// If you updated the list of recommended apps,
|
||||
// you can simply update this number to match the new length
|
||||
expect(spies.get_app.callCount).to.equal(26);
|
||||
}
|
||||
|
||||
// Second call
|
||||
{
|
||||
const { get_launch_apps, req_mock, res_mock, spies } = get_mock_context();
|
||||
await get_launch_apps(req_mock, res_mock);
|
||||
|
||||
const call = res_mock.send.firstCall;
|
||||
response = call.args[0];
|
||||
console.log('response', response);
|
||||
|
||||
expect(response).to.be.an('object');
|
||||
expect(res_mock.send.calledOnce).to.equal(true, 'res.send should be called once');
|
||||
|
||||
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,
|
||||
}))
|
||||
);
|
||||
const call = res_mock.send.firstCall;
|
||||
response = call.args[0];
|
||||
|
||||
expect(response).to.be.an('object');
|
||||
|
||||
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,
|
||||
}))
|
||||
);
|
||||
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,
|
||||
}))
|
||||
);
|
||||
|
||||
expect(spies.get_app.callCount).to.equal(
|
||||
data_appopens.length, 'get_app only called for recents on second call');
|
||||
}
|
||||
})
|
||||
});
|
||||
Reference in New Issue
Block a user