tests/cli-min-version.test.ts
Rama main · réplica de lectura del repositorio original.
import { randomUUID } from 'node:crypto'
import { writeFile } from 'node:fs/promises'
import { join } from 'node:path'
import { afterAll, beforeAll, describe, expect, it } from 'vitest'
import { createTestSDK, uploadBundleSDK } from './cli-sdk-utils'
import { cleanupCli, getSemver, prepareCli } from './cli-utils'
import { createIsolatedSeedAppOptions, executeSQL, getSupabaseClient, resetAndSeedAppData, resetAppData, resetAppDataStats } from './test-utils'
async function writeBundleContent(appId: string, marker: string) {
const indexHtmlPath = join(process.cwd(), 'temp_cli_test', appId, 'dist', 'index.html')
await writeFile(indexHtmlPath, `<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CLI Min Version Test</title>
</head>
<body>
<h1>${marker}</h1>
<script>
if (window.CapacitorUpdater) {
window.CapacitorUpdater.notifyAppReady();
}
</script>
</body>
</html>`)
}
describe('tests min version', () => {
const id = randomUUID()
const APPNAME = `com.cli_min_version_${id}`
const seedOptions = createIsolatedSeedAppOptions()
beforeAll(async () => {
await Promise.all([
resetAndSeedAppData(APPNAME, seedOptions),
prepareCli(APPNAME, false, false), // Use main project dependencies instead
])
})
afterAll(async () => {
await Promise.all([
cleanupCli(APPNAME),
resetAppData(APPNAME),
resetAppDataStats(APPNAME),
])
})
it('should test auto min version flag', async () => {
const supabase = getSupabaseClient()
const { error } = await supabase.from('app_versions').update({ min_update_version: '1.0.0' }).eq('name', '1.0.0').eq('app_id', APPNAME).throwOnError()
expect(error).toBeNull()
// Use a fixed version instead of timestamp-based to avoid timing issues
const testId = Math.floor(Math.random() * 1000000)
const semverDefault = `1.0.${testId}`
const channelName = `min-version-${testId}`
const packageJsonPath = join(process.cwd(), 'temp_cli_test', APPNAME, 'package.json')
const sdk = createTestSDK()
const createChannelResult = await sdk.addChannel({
appId: APPNAME,
channelId: channelName,
})
expect(createChannelResult.success).toBe(true)
const linkSeedBundleResult = await sdk.updateChannel({
appId: APPNAME,
channelId: channelName,
bundle: '1.0.0',
})
expect(linkSeedBundleResult.success).toBe(true)
await writeBundleContent(APPNAME, `auto-min-${semverDefault}`)
// Upload with auto-min-update-version:app_versions!channels_version_fkey(needs metadata check enabled)
const result0 = await uploadBundleSDK(APPNAME, semverDefault, channelName, {
ignoreCompatibilityCheck: false,
packageJsonPaths: packageJsonPath,
autoMinUpdateVersion: true,
})
expect(result0.success).toBe(true)
// Check that min_update_version was auto-set
const { data, error: checkError } = await supabase
.from('app_versions')
.select('min_update_version')
.eq('name', semverDefault)
.eq('app_id', APPNAME)
.single()
.throwOnError()
expect(checkError).toBeNull()
// The auto-min-update-version should have set a value
expect(data?.min_update_version).toBeDefined()
const { error: clearError } = await supabase
.from('app_versions')
.update({ min_update_version: null })
.eq('name', semverDefault)
.eq('app_id', APPNAME)
.throwOnError()
expect(clearError).toBeNull()
// Upload a new version with auto-min-update-version
// This should FAIL because native_packages aren't set on previous version
const semverNew = getSemver(semverDefault)
await writeBundleContent(APPNAME, `auto-min-${semverNew}`)
const result1 = await uploadBundleSDK(APPNAME, semverNew, channelName, {
ignoreCompatibilityCheck: false,
packageJsonPaths: packageJsonPath,
autoMinUpdateVersion: true,
})
const result1Error = result1.error ?? ''
// This upload should fail with auto-setting compatibility error
expect(result1.success).toBe(false)
expect(
result1Error.includes('Cannot auto set compatibility')
|| result1Error.includes('Error fetching native packages')
|| result1Error.includes('Invalid remote min update version'),
).toBe(true)
// The new version should NOT exist because upload failed
const { data: dataNew, error: checkErrorNew } = await supabase
.from('app_versions')
.select('min_update_version')
.eq('name', semverNew)
.eq('app_id', APPNAME)
.single()
expect(checkErrorNew).toBeDefined()
expect(dataNew).toBeNull()
// Simulate a channel whose current bundle has no compatibility metadata.
await executeSQL(
'DELETE FROM public.app_versions WHERE app_id = $1 AND name = ANY($2::varchar[])',
[APPNAME, [semverDefault, semverNew]],
)
const relinkSeed = await sdk.updateChannel({
appId: APPNAME,
channelId: channelName,
bundle: '1.0.0',
})
expect(relinkSeed.success).toBe(true)
// Upload with auto-min-update-version when previous version has no native_packages
const semverWithNull = `1.0.${testId + 2}`
await writeBundleContent(APPNAME, `auto-min-${semverWithNull}`)
const result2 = await uploadBundleSDK(APPNAME, semverWithNull, channelName, {
ignoreCompatibilityCheck: false,
packageJsonPaths: packageJsonPath,
autoMinUpdateVersion: true,
})
// Should succeed - it's first upload with compatibility check after clearing metadata.
expect(result2.success).toBe(true)
}, 30000)
})