Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,14 @@ class CdnDefinitionProvider extends DefinitionProvider {
// --------------------------------------------------------

void _rebuildFromRoot(Map<String, dynamic> root) {
// Validate before mutating in-memory or persisted cache. A background
// refresh that clears first and then bails on missing artifacts would
// otherwise wipe a working session and persist an unusable manifest.
if (_asMap(root['artifacts']) == null) {
throw ConfigError(
'CDN manifest is missing a valid artifacts section.');
}

// reset caches/state
_artifactCache.clear();
_screenNameMappings.clear();
Expand All @@ -729,8 +737,7 @@ class CdnDefinitionProvider extends DefinitionProvider {
_appConfig = null;
_applySecretsFromRoot(root);

final artifacts = _asMap(root['artifacts']);
if (artifacts == null) return;
final artifacts = _asMap(root['artifacts'])!;

// 1) config
final configMap = _asMap(artifacts['config']);
Expand Down
16 changes: 16 additions & 0 deletions modules/ensemble/test/cdn_provider_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:ui';
import 'package:ensemble/ensemble.dart';
import 'package:ensemble/framework/definition_providers/cdn_provider.dart';
import 'package:ensemble/framework/definition_providers/provider.dart';
import 'package:ensemble/framework/error_handling.dart';
import 'package:ensemble/util/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
Expand Down Expand Up @@ -121,6 +122,21 @@ void main() {
final prefs = await SharedPreferences.getInstance();
expect(prefs.getStringList(cacheKey), isNull);
});

test('rejects manifest without artifacts before mutating in-memory cache',
() async {
final provider = CdnDefinitionProvider('missing-artifacts-app');
await provider.applyRuntimeManifestForTesting(_manifestWithNewKey());

expect(provider.getSupportedLanguages(), isNotEmpty);

expect(
() => provider.rebuildManifestCacheForTesting({}),
throwsA(isA<ConfigError>()),
);

expect(provider.getSupportedLanguages(), isNotEmpty);
});
});

group('CDN translation runtime refresh', () {
Expand Down
Loading