52 lines
2.6 KiB
TypeScript
52 lines
2.6 KiB
TypeScript
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
|
|
const root = path.resolve(__dirname, '..');
|
|
const android = path.join(root, 'android', 'app', 'src', 'main');
|
|
|
|
function read(relativePath: string): string {
|
|
return fs.readFileSync(path.join(android, relativePath), 'utf8');
|
|
}
|
|
|
|
describe('Android incoming media native contract', () => {
|
|
test('Activity capture does not perform provider or file I/O', () => {
|
|
const activity = read(path.join('java', 'com', 'd3ro', 'voice', 'MainActivity.kt'));
|
|
expect(activity).toContain('D3ROIncomingMediaIntents.capture(applicationContext, intent)');
|
|
expect(activity).not.toContain('contentResolver');
|
|
expect(activity).not.toContain('openInputStream');
|
|
expect(activity).not.toContain('query(');
|
|
expect(activity).not.toContain('getType(');
|
|
});
|
|
|
|
test('resolver, copy and MP4 extraction are worker-owned and publish one-shot failures', () => {
|
|
const source = read(path.join('java', 'com', 'd3ro', 'voice', 'D3ROIncomingMediaIntents.kt'));
|
|
expect(source).toContain('executor.execute { processCaptured');
|
|
expect(source).toContain('context.contentResolver.getType(uri)');
|
|
expect(source).toContain('context.contentResolver.query(');
|
|
expect(source).toContain('context.contentResolver.openInputStream(uri)');
|
|
expect(source).toContain('PendingFailure');
|
|
expect(source).toContain('clearPendingMetadata(context)');
|
|
expect(source).toContain('MediaFormat.MIMETYPE_AUDIO_AAC');
|
|
expect(source).toContain('"video-no-audio"');
|
|
expect(source).toContain('"video-audio-unsupported"');
|
|
});
|
|
|
|
test('manifest advertises only MP4 video while keeping the validated audio family', () => {
|
|
const manifest = read('AndroidManifest.xml');
|
|
expect(manifest).toContain('android.intent.action.SEND');
|
|
expect(manifest).toContain('android.intent.action.VIEW');
|
|
expect(manifest).toContain('android:mimeType="video/mp4"');
|
|
expect(manifest).not.toContain('android:mimeType="audio/*"');
|
|
expect(manifest).not.toContain('android:mimeType="video/*"');
|
|
expect(manifest).not.toContain('android:mimeType="video/webm"');
|
|
expect(manifest).not.toContain('android:mimeType="video/quicktime"');
|
|
expect(manifest).not.toContain('android:mimeType="video/3gpp"');
|
|
});
|
|
|
|
test('manifest exports only the canonical d3ro-voice custom scheme', () => {
|
|
const manifest = read('AndroidManifest.xml');
|
|
expect(manifest).toContain('android:scheme="d3ro-voice" android:host="auth-callback"');
|
|
expect(manifest).toContain('android:scheme="d3ro-voice" android:host="accept-invite"');
|
|
expect(manifest).not.toContain('android:scheme="d3ro"');
|
|
});
|
|
});
|