diff --git a/lib/data/globals.dart b/lib/data/globals.dart index 5993c4f..6a46a28 100644 --- a/lib/data/globals.dart +++ b/lib/data/globals.dart @@ -72,7 +72,8 @@ class Globals { /// File system path (relative to assets directory) /// of the resources in a language - /// Must be the main folder name that is inside the zip file we download + /// Must be the main folder name that is inside the zip file we download, + /// e.g. 'html-en-main' static String getLocalPath(String languageCode) { return '$htmlPath-$languageCode-$branch'; } diff --git a/lib/data/languages.dart b/lib/data/languages.dart index 5823221..1f5d408 100644 --- a/lib/data/languages.dart +++ b/lib/data/languages.dart @@ -145,13 +145,15 @@ class LanguageController extends FamilyNotifier { await _checkConsistency(dir, pages); // Register available images - await for (var file in fileSystem - .directory(join(path, 'files')) - .list(recursive: false, followLinks: false)) { - if (file is File) { - images[basename(file.path)] = Image(basename(file.path)); - } else { - debugPrint("Found unexpected element $file in files/ directory"); + var filesDir = fileSystem.directory(join(path, 'files')); + if (await filesDir.exists()) { + await for (var file + in filesDir.list(recursive: false, followLinks: false)) { + if (file is File) { + images[basename(file.path)] = Image(basename(file.path)); + } else { + debugPrint("Found unexpected element $file in files/ directory"); + } } } state = Language( diff --git a/test/languages_test.dart b/test/languages_test.dart index a02f8a3..a26f2e2 100644 --- a/test/languages_test.dart +++ b/test/languages_test.dart @@ -134,6 +134,31 @@ void main() { } expect(deTest.state.downloaded, false); }); + + test('A missing files/ dir should be no problem', () async { + // We construct a file system in memory with structure/contents.json + // filled correctly but where HTML files and the files/ dir are missing + var fileSystem = MemoryFileSystem(); + await fileSystem + .directory('assets-de/html-de-main/structure') + .create(recursive: true); + var readFileSystem = ChrootFileSystem( + const LocalFileSystem(), path.canonicalize('test/')); + String jsonPath = 'assets-de/html-de-main/structure/contents.json'; + var contentsJson = fileSystem.file(jsonPath); + contentsJson + .writeAsString(await readFileSystem.file(jsonPath).readAsString()); + final container = ProviderContainer(overrides: [ + languageProvider + .overrideWith(() => LanguageController(assetsController: mock)), + fileSystemProvider.overrideWith((ref) => fileSystem), + ]); + + // init() should work (even if expected HTML files are missing) + final deTest = container.read(languageProvider('de').notifier); + await deTest.init(); + expect(deTest.state.downloaded, true); + }); }); test('Test everything with real content from test/assets-de/', () async {