Restore Gaia settings and media workflows, extend native network adapters, and align the APK payload. Generate French/English changelogs and website entries from the simplified JSON source. Validation: shared JS and Tundra unit tests; desktop workflows and persistence; signed APK payload parity; Sargo RAM and installed startup with boot readback. Android runtime qualification is recorded separately.
34 lines
2.8 KiB
JavaScript
34 lines
2.8 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import {Messages} from '../host/Messages.sys.mjs';
|
|
import {mmsPayload,receivedMms} from '../services/mms.mjs';
|
|
const app={manifest:{permissions:{sms:{}}}};
|
|
const part={id:'photo.jpg',location:'photo.jpg',content:{__vulpesBlobV1:true,type:'image/jpeg',base64:'/9j/2Q=='}};
|
|
const payload={receivers:['+15550199'],subject:'Photo',smil:'',attachments:[part]};
|
|
function store(){let rows=[];return {run:async(_,op,args)=>op==='get'?{value:structuredClone(rows)}:(rows=structuredClone(args[0]))};}
|
|
test('MMS remains pending until MMSC acceptance and keeps attachments',async()=>{
|
|
const events=[];let status={state:'pending'};
|
|
const mms={validate:mmsPayload,send:async p=>{assert.deepEqual(p,payload);return {path:'id',state:'pending'};},status:async()=>status};
|
|
const s=new Messages(store(),null,(t,m)=>events.push([t,m]),null,mms);
|
|
const message=await s.request(app,{operation:'sendMMS',args:[payload]});assert.equal(message.delivery,'sending');
|
|
await s.refreshOutgoing();assert.equal(events.length,1);
|
|
status={state:'sent'};await s.refreshOutgoing();assert.equal(events.at(-1)[0],'sent');
|
|
assert.deepEqual(events.at(-1)[1].attachments,[part]);
|
|
assert.deepEqual((await s.request(app,{operation:'getThreads'}))[0].participants,payload.receivers);
|
|
});
|
|
test('bearer failure retains failed MMS bubble without a sent event',async()=>{
|
|
const events=[];const s=new Messages(store(),null,t=>events.push(t),null,{validate:mmsPayload,send:async()=>({path:'id'}),status:async()=>({state:'failed',error:'MMS_DATA_UNAVAILABLE'})});
|
|
await s.request(app,{operation:'sendMMS',args:[payload]});await s.refreshOutgoing();
|
|
const m=(await s.request(app,{operation:'getMessages'}))[0];assert.equal(m.delivery,'error');assert.equal(m.error,'MMS_DATA_UNAVAILABLE');assert.deepEqual(m.attachments,[part]);assert.deepEqual(events,['sending','failed']);
|
|
});
|
|
test('incoming MMS is deduplicated and preserves native attachment blobs',async()=>{
|
|
const row=receivedMms({receipt:'push-1',type:'mms',sender:'+15550199',receivers:[],parts:[{id:'photo.jpg',type:'image/jpeg',data:'/9j/2Q=='},{id:'text.txt',type:'text/plain',data:btoa('Hello')}]});
|
|
const s=new Messages(store());const a=await s.receive(row),b=await s.receive(row);
|
|
assert.equal(a.id,b.id);assert.equal(a.body,'Hello');assert.equal(a.type,'mms');assert.equal(a.attachments[0].content.base64,part.content.base64);
|
|
assert.equal((await s.request(app,{operation:'getThreads'}))[0].lastMessageType,'mms');
|
|
});
|
|
test('reject invalid recipients, missing blobs and oversized MMS',()=>{
|
|
assert.throws(()=>mmsPayload({...payload,receivers:['file:///etc/passwd']}));
|
|
assert.throws(()=>mmsPayload({...payload,attachments:[{content:{}}]}));
|
|
assert.throws(()=>mmsPayload({...payload,attachments:[{...part,content:{...part.content,base64:'A'.repeat(900000)}}]}));
|
|
});
|