75 lines
2.1 KiB
JavaScript
75 lines
2.1 KiB
JavaScript
import { readFileSync } from 'node:fs';
|
|
import {
|
|
collection,
|
|
getDocs,
|
|
orderBy,
|
|
query,
|
|
where,
|
|
} from 'firebase/firestore';
|
|
import {
|
|
createTestEnvironment,
|
|
seedDocuments,
|
|
} from '../support/environment.mjs';
|
|
|
|
const manifest = JSON.parse(
|
|
readFileSync(new URL('../../firestore.indexes.json', import.meta.url), 'utf8'),
|
|
);
|
|
const deliberatelyMissingFields = [
|
|
['fandomId', 'ASCENDING'],
|
|
['visibility', 'ASCENDING'],
|
|
['createdAt', 'DESCENDING'],
|
|
['likeCount', 'DESCENDING'],
|
|
];
|
|
const hasDeliberatelyMissingIndex = manifest.indexes.some((index) => {
|
|
if (index.collectionGroup !== 'posts' || index.fields.length !== deliberatelyMissingFields.length) {
|
|
return false;
|
|
}
|
|
|
|
return deliberatelyMissingFields.every(
|
|
([fieldPath, order], position) =>
|
|
index.fields[position].fieldPath === fieldPath && index.fields[position].order === order,
|
|
);
|
|
});
|
|
|
|
if (hasDeliberatelyMissingIndex) {
|
|
throw new Error('Probe precondition failed: deliberately missing composite index exists');
|
|
}
|
|
|
|
console.log('INDEX MANIFEST CONTROL PASS: required 4-field posts composite index -> absent');
|
|
|
|
const testEnvironment = await createTestEnvironment();
|
|
|
|
try {
|
|
await testEnvironment.clearFirestore();
|
|
await seedDocuments(testEnvironment, {
|
|
'posts/post-1': {
|
|
fandomId: 'fandom-a',
|
|
visibility: 'visible',
|
|
createdAt: '2026-08-08T00:00:00Z',
|
|
likeCount: 1,
|
|
},
|
|
'posts/post-2': {
|
|
fandomId: 'fandom-a',
|
|
visibility: 'visible',
|
|
createdAt: '2026-08-08T01:00:00Z',
|
|
likeCount: 2,
|
|
},
|
|
});
|
|
|
|
const firestore = testEnvironment.authenticatedContext('alice').firestore();
|
|
const missingIndexQuery = query(
|
|
collection(firestore, 'posts'),
|
|
where('fandomId', '==', 'fandom-a'),
|
|
where('visibility', '==', 'visible'),
|
|
orderBy('createdAt', 'desc'),
|
|
orderBy('likeCount', 'desc'),
|
|
);
|
|
const result = await getDocs(missingIndexQuery);
|
|
|
|
console.log(`EMULATOR MISSING-INDEX QUERY RESULT: allowed (${result.size} documents)`);
|
|
console.log('INDEX VALIDATION VERDICT: unsupported — emulator does not enforce composite indexes');
|
|
} finally {
|
|
await testEnvironment.cleanup();
|
|
}
|
|
|