diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 5117dcc0af..4ccca8f067 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -33,7 +33,7 @@ jobs: if: github.event.pull_request.draft != true strategy: matrix: - os: [ubuntu-latest] + os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} diff --git a/frontend/appflowy_flutter/integration_test/database_calendar_test.dart b/frontend/appflowy_flutter/integration_test/database_calendar_test.dart index 7268e2134d..25e3cc8ff5 100644 --- a/frontend/appflowy_flutter/integration_test/database_calendar_test.dart +++ b/frontend/appflowy_flutter/integration_test/database_calendar_test.dart @@ -10,21 +10,6 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('database', () { - const location = 'appflowy'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(location); - }); - - tearDownAll(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('update calendar layout', (tester) async { await tester.initializeAppFlowy(); await tester.tapGoButton(); diff --git a/frontend/appflowy_flutter/integration_test/database_cell_test.dart b/frontend/appflowy_flutter/integration_test/database_cell_test.dart index ec7dbe477f..27b19ec4ef 100644 --- a/frontend/appflowy_flutter/integration_test/database_cell_test.dart +++ b/frontend/appflowy_flutter/integration_test/database_cell_test.dart @@ -11,21 +11,6 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('grid cell', () { - const location = 'appflowy'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(location); - }); - - tearDownAll(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('edit text cell', (tester) async { await tester.initializeAppFlowy(); await tester.tapGoButton(); diff --git a/frontend/appflowy_flutter/integration_test/database_field_test.dart b/frontend/appflowy_flutter/integration_test/database_field_test.dart index ec4f1f4d35..952b401259 100644 --- a/frontend/appflowy_flutter/integration_test/database_field_test.dart +++ b/frontend/appflowy_flutter/integration_test/database_field_test.dart @@ -10,21 +10,6 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('grid page', () { - const location = 'appflowy'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(location); - }); - - tearDownAll(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('rename existing field', (tester) async { await tester.initializeAppFlowy(); await tester.tapGoButton(); diff --git a/frontend/appflowy_flutter/integration_test/database_filter_test.dart b/frontend/appflowy_flutter/integration_test/database_filter_test.dart index de509a8b84..1ae7488016 100644 --- a/frontend/appflowy_flutter/integration_test/database_filter_test.dart +++ b/frontend/appflowy_flutter/integration_test/database_filter_test.dart @@ -5,27 +5,11 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'util/database_test_op.dart'; -import 'util/util.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('grid', () { - const location = 'import_files'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(location); - }); - - tearDownAll(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('add text filter', (tester) async { await tester.openV020database(); diff --git a/frontend/appflowy_flutter/integration_test/database_row_page_test.dart b/frontend/appflowy_flutter/integration_test/database_row_page_test.dart index 825cd315a7..bfd5a5416b 100644 --- a/frontend/appflowy_flutter/integration_test/database_row_page_test.dart +++ b/frontend/appflowy_flutter/integration_test/database_row_page_test.dart @@ -14,21 +14,6 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('grid', () { - const location = 'appflowy'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(location); - }); - - tearDownAll(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('row details page opens', (tester) async { await tester.initializeAppFlowy(); await tester.tapGoButton(); diff --git a/frontend/appflowy_flutter/integration_test/database_row_test.dart b/frontend/appflowy_flutter/integration_test/database_row_test.dart index 14a336a89f..c3e48823ac 100644 --- a/frontend/appflowy_flutter/integration_test/database_row_test.dart +++ b/frontend/appflowy_flutter/integration_test/database_row_test.dart @@ -8,21 +8,6 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('grid', () { - const location = 'appflowy'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(location); - }); - - tearDownAll(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('create row of the grid', (tester) async { await tester.initializeAppFlowy(); await tester.tapGoButton(); diff --git a/frontend/appflowy_flutter/integration_test/database_setting_test.dart b/frontend/appflowy_flutter/integration_test/database_setting_test.dart index ba4e88ea9f..6b0b7fe992 100644 --- a/frontend/appflowy_flutter/integration_test/database_setting_test.dart +++ b/frontend/appflowy_flutter/integration_test/database_setting_test.dart @@ -9,21 +9,6 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('grid', () { - const location = 'appflowy'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(location); - }); - - tearDownAll(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('update layout', (tester) async { await tester.initializeAppFlowy(); await tester.tapGoButton(); diff --git a/frontend/appflowy_flutter/integration_test/database_share_test.dart b/frontend/appflowy_flutter/integration_test/database_share_test.dart index 15a3a33548..edb6baceaa 100644 --- a/frontend/appflowy_flutter/integration_test/database_share_test.dart +++ b/frontend/appflowy_flutter/integration_test/database_share_test.dart @@ -1,66 +1,15 @@ -import 'dart:io'; - import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'util/database_test_op.dart'; -import 'util/mock/mock_file_picker.dart'; -import 'util/util.dart'; -import 'package:path/path.dart' as p; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('database', () { - const location = 'import_files'; - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(location); - }); - - tearDownAll(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('import v0.2.0 database data', (tester) async { - await tester.initializeAppFlowy(); - await tester.tapGoButton(); - - // expect to see a readme page - tester.expectToSeePageName(readme); - - await tester.tapAddButton(); - await tester.tapImportButton(); - - final testFileNames = ['v020.afdb']; - final fileLocation = await tester.currentFileLocation(); - for (final fileName in testFileNames) { - final str = await rootBundle.loadString( - p.join( - 'assets/test/workspaces/database', - fileName, - ), - ); - File(p.join(fileLocation, fileName)).writeAsStringSync(str); - } - // mock get files - await mockPickFilePaths(testFileNames, name: location); - await tester.tapDatabaseRawDataButton(); - await tester.openPage('v020'); - - // check the import content - // await tester.assertCellContent( - // rowIndex: 7, - // fieldType: FieldType.RichText, - // // fieldName: 'Name', - // content: '', - // ); + await tester.openV020database(); // check the text cell final textCells = ['A', 'B', 'C', 'D', 'E', '', '', '', '', '']; diff --git a/frontend/appflowy_flutter/integration_test/database_sort_test.dart b/frontend/appflowy_flutter/integration_test/database_sort_test.dart index 26272be0ab..6f7f0273db 100644 --- a/frontend/appflowy_flutter/integration_test/database_sort_test.dart +++ b/frontend/appflowy_flutter/integration_test/database_sort_test.dart @@ -3,27 +3,11 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'util/database_test_op.dart'; -import 'util/util.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('grid', () { - const location = 'import_files'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(location); - }); - - tearDownAll(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('add text sort', (tester) async { await tester.openV020database(); // create a filter diff --git a/frontend/appflowy_flutter/integration_test/database_view_test.dart b/frontend/appflowy_flutter/integration_test/database_view_test.dart index 7d787f2fef..99ccd25b97 100644 --- a/frontend/appflowy_flutter/integration_test/database_view_test.dart +++ b/frontend/appflowy_flutter/integration_test/database_view_test.dart @@ -11,21 +11,6 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('database', () { - const location = 'appflowy'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(location); - }); - - tearDownAll(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('create linked view', (tester) async { await tester.initializeAppFlowy(); await tester.tapGoButton(); diff --git a/frontend/appflowy_flutter/integration_test/document/cover_image_test.dart b/frontend/appflowy_flutter/integration_test/document/cover_image_test.dart index 20b84d0755..5bcf4b7b43 100644 --- a/frontend/appflowy_flutter/integration_test/document/cover_image_test.dart +++ b/frontend/appflowy_flutter/integration_test/document/cover_image_test.dart @@ -9,21 +9,6 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('cover image', () { - const location = 'cover_image'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(location); - }); - - tearDownAll(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('document cover tests', (tester) async { await tester.initializeAppFlowy(); await tester.tapGoButton(); diff --git a/frontend/appflowy_flutter/integration_test/document/document_test.dart b/frontend/appflowy_flutter/integration_test/document/document_test.dart index 3efbbee43b..cd366e75a3 100644 --- a/frontend/appflowy_flutter/integration_test/document/document_test.dart +++ b/frontend/appflowy_flutter/integration_test/document/document_test.dart @@ -10,21 +10,6 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('document', () { - const location = 'appflowy'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(location); - }); - - tearDownAll(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('create a new document when launching app in first time', (tester) async { await tester.initializeAppFlowy(); diff --git a/frontend/appflowy_flutter/integration_test/document/document_with_database_test.dart b/frontend/appflowy_flutter/integration_test/document/document_with_database_test.dart index 5cae41e478..b121a8db59 100644 --- a/frontend/appflowy_flutter/integration_test/document/document_with_database_test.dart +++ b/frontend/appflowy_flutter/integration_test/document/document_with_database_test.dart @@ -14,17 +14,6 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('database view in document', () { - const location = 'database_view'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('insert a referenced grid', (tester) async { await tester.initializeAppFlowy(); await tester.tapGoButton(); diff --git a/frontend/appflowy_flutter/integration_test/document/document_with_inline_page_test.dart b/frontend/appflowy_flutter/integration_test/document/document_with_inline_page_test.dart index c9a0bead19..437f165d0c 100644 --- a/frontend/appflowy_flutter/integration_test/document/document_with_inline_page_test.dart +++ b/frontend/appflowy_flutter/integration_test/document/document_with_inline_page_test.dart @@ -11,17 +11,6 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('inline page view in document', () { - const location = 'inline_page'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('insert a inline page - grid', (tester) async { await tester.initializeAppFlowy(); await tester.tapGoButton(); diff --git a/frontend/appflowy_flutter/integration_test/document/edit_document_test.dart b/frontend/appflowy_flutter/integration_test/document/edit_document_test.dart index 9930014692..4d986f26df 100644 --- a/frontend/appflowy_flutter/integration_test/document/edit_document_test.dart +++ b/frontend/appflowy_flutter/integration_test/document/edit_document_test.dart @@ -13,17 +13,6 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('edit document', () { - const location = 'appflowy'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('redo & undo', (tester) async { await tester.initializeAppFlowy(); await tester.tapGoButton(); diff --git a/frontend/appflowy_flutter/integration_test/import_files_test.dart b/frontend/appflowy_flutter/integration_test/import_files_test.dart index 5743e01f76..ce302ba53d 100644 --- a/frontend/appflowy_flutter/integration_test/import_files_test.dart +++ b/frontend/appflowy_flutter/integration_test/import_files_test.dart @@ -12,23 +12,8 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('import files', () { - const location = 'import_files'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(location); - }); - - tearDownAll(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('import multiple markdown files', (tester) async { - await tester.initializeAppFlowy(); + final context = await tester.initializeAppFlowy(); await tester.tapGoButton(); // expect to see a readme page @@ -38,18 +23,21 @@ void main() { await tester.tapImportButton(); final testFileNames = ['test1.md', 'test2.md']; - final fileLocation = await tester.currentFileLocation(); + final paths = []; for (final fileName in testFileNames) { final str = await rootBundle.loadString( - p.join( - 'assets/test/workspaces/markdowns', - fileName, - ), + 'assets/test/workspaces/markdowns/$fileName', ); - File(p.join(fileLocation, fileName)).writeAsStringSync(str); + final path = p.join(context.applicationDataDirectory, fileName); + paths.add(path); + File(path).writeAsStringSync(str); } // mock get files - await mockPickFilePaths(testFileNames, name: location); + await mockPickFilePaths( + paths: testFileNames + .map((e) => p.join(context.applicationDataDirectory, e)) + .toList(), + ); await tester.tapTextAndMarkdownButton(); diff --git a/frontend/appflowy_flutter/integration_test/language_test.dart b/frontend/appflowy_flutter/integration_test/language_test.dart index 40b774a1d9..94aeef0e9d 100644 --- a/frontend/appflowy_flutter/integration_test/language_test.dart +++ b/frontend/appflowy_flutter/integration_test/language_test.dart @@ -8,16 +8,6 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('document', () { - const location = 'appflowy'; - - setUpAll(() async { - await TestFolder.setTestLocation(location); - }); - - tearDownAll(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets( 'change the language successfully when launching the app for the first time', (tester) async { diff --git a/frontend/appflowy_flutter/integration_test/plugins/outline_block_test.dart b/frontend/appflowy_flutter/integration_test/plugins/outline_block_test.dart index f9d66328a8..3353094976 100644 --- a/frontend/appflowy_flutter/integration_test/plugins/outline_block_test.dart +++ b/frontend/appflowy_flutter/integration_test/plugins/outline_block_test.dart @@ -12,17 +12,6 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('outline block test', () { - const location = 'outline_test'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('insert an outline block', (tester) async { await tester.initializeAppFlowy(); await tester.tapGoButton(); diff --git a/frontend/appflowy_flutter/integration_test/share_markdown_test.dart b/frontend/appflowy_flutter/integration_test/share_markdown_test.dart index a39575e49b..55ec5b890c 100644 --- a/frontend/appflowy_flutter/integration_test/share_markdown_test.dart +++ b/frontend/appflowy_flutter/integration_test/share_markdown_test.dart @@ -3,7 +3,7 @@ import 'dart:io'; import 'package:appflowy/plugins/document/presentation/share/share_button.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; - +import 'package:path/path.dart' as p; import 'util/mock/mock_file_picker.dart'; import 'util/util.dart'; @@ -11,30 +11,17 @@ void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('share markdown in document page', () { - const location = 'markdown'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(location); - }); - - tearDownAll(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('click the share button in document page', (tester) async { - await tester.initializeAppFlowy(); + final context = await tester.initializeAppFlowy(); await tester.tapGoButton(); // expect to see a readme page tester.expectToSeePageName(readme); // mock the file picker - final path = await mockSaveFilePath(location, 'test.md'); + final path = await mockSaveFilePath( + p.join(context.applicationDataDirectory, 'test.md'), + ); // click the share button and select markdown await tester.tapShareButton(); await tester.tapMarkdownButton(); @@ -52,7 +39,7 @@ void main() { testWidgets( 'share the markdown after renaming the document name', (tester) async { - await tester.initializeAppFlowy(); + final context = await tester.initializeAppFlowy(); await tester.tapGoButton(); // expect to see a readme page @@ -65,8 +52,12 @@ void main() { final shareButton = find.byType(ShareActionList); final shareButtonState = tester.state(shareButton) as ShareActionListState; - final path = - await mockSaveFilePath(location, '${shareButtonState.name}.md'); + final path = await mockSaveFilePath( + p.join( + context.applicationDataDirectory, + '${shareButtonState.name}.md', + ), + ); // click the share button and select markdown await tester.tapShareButton(); diff --git a/frontend/appflowy_flutter/integration_test/switch_folder_test.dart b/frontend/appflowy_flutter/integration_test/switch_folder_test.dart index 177bc7142b..3ccd95d038 100644 --- a/frontend/appflowy_flutter/integration_test/switch_folder_test.dart +++ b/frontend/appflowy_flutter/integration_test/switch_folder_test.dart @@ -1,48 +1,36 @@ +import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy/startup/tasks/prelude.dart'; import 'package:appflowy/workspace/application/settings/prelude.dart'; -import 'package:appflowy/workspace/application/settings/settings_location_cubit.dart'; -import 'package:flowy_infra/uuid.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; - +import 'package:path/path.dart' as p; import 'util/mock/mock_file_picker.dart'; import 'util/util.dart'; -import 'package:path/path.dart' as p; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); group('customize the folder path', () { - const location = 'appflowy'; - - setUp(() async { - await TestFolder.cleanTestLocation(location); - await TestFolder.setTestLocation(location); - }); - - tearDown(() async { - await TestFolder.cleanTestLocation(location); - }); - - tearDownAll(() async { - await TestFolder.cleanTestLocation(null); - }); - testWidgets('switch to B from A, then switch to A again', (tester) async { - final userA = uuid(); - final userB = uuid(); + const userA = 'UserA'; + const userB = 'UserB'; - await TestFolder.cleanTestLocation(userA); - await TestFolder.cleanTestLocation(userB); - await TestFolder.setTestLocation(p.join(userA, appFlowyDataFolder)); - - await tester.initializeAppFlowy(); + final initialPath = p.join(userA, appFlowyDataFolder); + final context = await tester.initializeAppFlowy( + pathExtension: initialPath, + ); + // remove the last extension + final rootPath = context.applicationDataDirectory.replaceFirst( + initialPath, + '', + ); await tester.tapGoButton(); tester.expectToSeeHomePage(); // switch to user B { - // set user name to userA + // set user name for userA await tester.openSettings(); await tester.openSettingsPage(SettingsPage.user); await tester.enterUserName(userA); @@ -51,12 +39,14 @@ void main() { await tester.pumpAndSettle(); // mock the file_picker result - await mockGetDirectoryPath(userB); + await mockGetDirectoryPath( + p.join(rootPath, userB), + ); await tester.tapCustomLocationButton(); await tester.pumpAndSettle(); tester.expectToSeeHomePage(); - // set user name to userB + // set user name for userB await tester.openSettings(); await tester.openSettingsPage(SettingsPage.user); await tester.enterUserName(userB); @@ -68,7 +58,9 @@ void main() { await tester.pumpAndSettle(); // mock the file_picker result - await mockGetDirectoryPath(userA); + await mockGetDirectoryPath( + p.join(rootPath, userA), + ); await tester.tapCustomLocationButton(); await tester.pumpAndSettle(); @@ -83,16 +75,15 @@ void main() { await tester.pumpAndSettle(); // mock the file_picker result - await mockGetDirectoryPath(userB); + await mockGetDirectoryPath( + p.join(rootPath, userB), + ); await tester.tapCustomLocationButton(); await tester.pumpAndSettle(); tester.expectToSeeHomePage(); tester.expectToSeeUserName(userB); } - - await TestFolder.cleanTestLocation(userA); - await TestFolder.cleanTestLocation(userB); }); testWidgets('reset to default location', (tester) async { @@ -109,8 +100,8 @@ void main() { await tester.restoreLocation(); expect( - await TestFolder.defaultDevelopmentLocation(), - await TestFolder.currentLocation(), + await appFlowyApplicationDataDirectory().then((value) => value.path), + await getIt().getPath(), ); }); }); diff --git a/frontend/appflowy_flutter/integration_test/util/base.dart b/frontend/appflowy_flutter/integration_test/util/base.dart index 2ff7b82668..0c4306cc5f 100644 --- a/frontend/appflowy_flutter/integration_test/util/base.dart +++ b/frontend/appflowy_flutter/integration_test/util/base.dart @@ -1,81 +1,77 @@ import 'dart:io'; -import 'package:appflowy/core/config/kv_keys.dart'; import 'package:appflowy/startup/entry_point.dart'; import 'package:appflowy/startup/startup.dart'; -import 'package:appflowy/startup/tasks/prelude.dart'; +import 'package:appflowy/workspace/application/settings/prelude.dart'; +import 'package:flowy_infra/uuid.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:shared_preferences/shared_preferences.dart'; -class TestFolder { - /// Location / Path +class FlowyTestContext { + FlowyTestContext({ + required this.applicationDataDirectory, + }); - /// Set a given AppFlowy data storage location under test environment. - /// - /// To pass null means clear the location. - /// - /// The file_picker is a system component and can't be tapped, so using logic instead of tapping. - /// - static Future setTestLocation(String? name) async { - final location = await testLocation(name); - SharedPreferences.setMockInitialValues({ - KVKeys.pathLocation: location.path, - }); - return; - } - - /// Clean the location. - static Future cleanTestLocation(String? name) async { - final dir = await testLocation(name); - await dir.delete(recursive: true); - return; - } - - /// Get current using location. - static Future currentLocation() async { - final prefs = await SharedPreferences.getInstance(); - return prefs.getString(KVKeys.pathLocation)!; - } - - /// Get default location under development environment. - static Future defaultDevelopmentLocation() async { - final dir = await appFlowyApplicationDataDirectory(); - return dir.path; - } - - /// Get default location under test environment. - static Future testLocation(String? name) async { - final dir = await getApplicationDocumentsDirectory(); - var path = '${dir.path}/flowy_test'; - if (name != null) { - path += '/$name'; - } - return Directory(path).create(recursive: true); - } + final String applicationDataDirectory; } extension AppFlowyTestBase on WidgetTester { - Future initializeAppFlowy() async { + Future initializeAppFlowy({ + // use to append after the application data directory + String? pathExtension, + }) async { + mockHotKeyManagerHandlers(); + final directory = await mockApplicationDataStorage( + pathExtension: pathExtension, + ); + + WidgetsFlutterBinding.ensureInitialized(); + await FlowyRunner.run( + FlowyApp(), + IntegrationMode.integrationTest, + ); + + await wait(3000); + await pumpAndSettle(const Duration(seconds: 2)); + return FlowyTestContext( + applicationDataDirectory: directory, + ); + } + + void mockHotKeyManagerHandlers() { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(const MethodChannel('hotkey_manager'), (MethodCall methodCall) async { if (methodCall.method == 'unregisterAll') { // do nothing } - return; }); + } - WidgetsFlutterBinding.ensureInitialized(); - await FlowyRunner.run(FlowyApp(), IntegrationMode.integrationTest); + Future mockApplicationDataStorage({ + // use to append after the application data directory + String? pathExtension, + }) async { + final dir = await getTemporaryDirectory(); - await wait(3000); - await pumpAndSettle(const Duration(seconds: 2)); + // Use a random uuid to avoid conflict. + String path = '${dir.path}/appflowy_integration_test/${uuid()}'; + if (pathExtension != null && pathExtension.isNotEmpty) { + path = '$path/$pathExtension'; + } + final directory = Directory(path); + if (!directory.existsSync()) { + await directory.create(recursive: true); + } + + MockApplicationDataStorage.initialPath = directory.path; + + return directory.path; } Future tapButton( diff --git a/frontend/appflowy_flutter/integration_test/util/common_operations.dart b/frontend/appflowy_flutter/integration_test/util/common_operations.dart index 1523f7467a..524f6cd61a 100644 --- a/frontend/appflowy_flutter/integration_test/util/common_operations.dart +++ b/frontend/appflowy_flutter/integration_test/util/common_operations.dart @@ -17,11 +17,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'util.dart'; extension CommonOperations on WidgetTester { - /// Get current file location of AppFlowy. - Future currentFileLocation() async { - return TestFolder.currentLocation(); - } - /// Tap the GetStart button on the launch page. Future tapGoButton() async { final goButton = find.byType(GoButton); diff --git a/frontend/appflowy_flutter/integration_test/util/database_test_op.dart b/frontend/appflowy_flutter/integration_test/util/database_test_op.dart index 43b50cd0c5..f8fbedc3c7 100644 --- a/frontend/appflowy_flutter/integration_test/util/database_test_op.dart +++ b/frontend/appflowy_flutter/integration_test/util/database_test_op.dart @@ -73,7 +73,7 @@ import 'mock/mock_file_picker.dart'; extension AppFlowyDatabaseTest on WidgetTester { Future openV020database() async { - await initializeAppFlowy(); + final context = await initializeAppFlowy(); await tapGoButton(); // expect to see a readme page @@ -83,18 +83,25 @@ extension AppFlowyDatabaseTest on WidgetTester { await tapImportButton(); final testFileNames = ['v020.afdb']; - final fileLocation = await currentFileLocation(); + final paths = []; for (final fileName in testFileNames) { - final str = await rootBundle.loadString( - p.join( - 'assets/test/workspaces/database', - fileName, - ), + // Don't use the p.join to build the path that used in loadString. It + // is not working on windows. + final str = await rootBundle + .loadString("assets/test/workspaces/database/$fileName"); + + // Write the content to the file. + final path = p.join( + context.applicationDataDirectory, + fileName, ); - File(p.join(fileLocation, fileName)).writeAsStringSync(str); + paths.add(path); + File(path).writeAsStringSync(str); } // mock get files - await mockPickFilePaths(testFileNames, name: 'import_files'); + await mockPickFilePaths( + paths: paths, + ); await tapDatabaseRawDataButton(); await openPage('v020'); } diff --git a/frontend/appflowy_flutter/integration_test/util/mock/mock_file_picker.dart b/frontend/appflowy_flutter/integration_test/util/mock/mock_file_picker.dart index 390d77d194..caaefea2d4 100644 --- a/frontend/appflowy_flutter/integration_test/util/mock/mock_file_picker.dart +++ b/frontend/appflowy_flutter/integration_test/util/mock/mock_file_picker.dart @@ -1,10 +1,6 @@ -import 'dart:io'; - import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/util/file_picker/file_picker_service.dart'; import 'package:file_picker/file_picker.dart' as fp; -import 'package:path/path.dart' as p; -import '../util.dart'; class MockFilePicker implements FilePickerService { MockFilePicker({ @@ -56,20 +52,21 @@ class MockFilePicker implements FilePickerService { } } -Future mockGetDirectoryPath(String? name) async { - final dir = await TestFolder.testLocation(name); +Future mockGetDirectoryPath( + String path, +) async { getIt.unregister(); getIt.registerFactory( () => MockFilePicker( - mockPath: dir.path, + mockPath: path, ), ); return; } -Future mockSaveFilePath(String? name, String fileName) async { - final dir = await TestFolder.testLocation(name); - final path = p.join(dir.path, fileName); +Future mockSaveFilePath( + String path, +) async { getIt.unregister(); getIt.registerFactory( () => MockFilePicker( @@ -79,18 +76,16 @@ Future mockSaveFilePath(String? name, String fileName) async { return path; } -Future> mockPickFilePaths( - List fileNames, { - String? name, - String? customPath, +Future> mockPickFilePaths({ + required List paths, }) async { - late final Directory dir; - if (customPath != null) { - dir = Directory(customPath); - } else { - dir = await TestFolder.testLocation(name); - } - final paths = fileNames.map((e) => p.join(dir.path, e)).toList(); + // late final Directory dir; + // if (customPath != null) { + // dir = Directory(customPath); + // } else { + // dir = await TestFolder.testLocation(applicationDataPath, name); + // } + // final paths = fileNames.map((e) => p.join(dir.path, e)).toList(); getIt.unregister(); getIt.registerFactory( () => MockFilePicker( diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/custom_cover_picker_bloc.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/custom_cover_picker_bloc.dart index b239ecf403..ecd45f3af7 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/custom_cover_picker_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/custom_cover_picker_bloc.dart @@ -2,7 +2,7 @@ import 'dart:io'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/util/file_picker/file_picker_service.dart'; -import 'package:appflowy/workspace/application/settings/settings_location_cubit.dart'; +import 'package:appflowy/workspace/application/settings/prelude.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:file_picker/file_picker.dart' as fp; diff --git a/frontend/appflowy_flutter/lib/startup/deps_resolver.dart b/frontend/appflowy_flutter/lib/startup/deps_resolver.dart index b7d15b793e..aac9e258f1 100644 --- a/frontend/appflowy_flutter/lib/startup/deps_resolver.dart +++ b/frontend/appflowy_flutter/lib/startup/deps_resolver.dart @@ -6,6 +6,7 @@ import 'package:appflowy/plugins/database_view/application/field/field_service.d import 'package:appflowy/plugins/database_view/application/setting/property_bloc.dart'; import 'package:appflowy/plugins/database_view/grid/application/grid_header_bloc.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/service/openai_client.dart'; +import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/auth/auth_service.dart'; import 'package:appflowy/user/application/auth/supabase_auth_service.dart'; import 'package:appflowy/user/application/user_listener.dart'; @@ -13,7 +14,6 @@ import 'package:appflowy/user/application/user_service.dart'; import 'package:appflowy/util/file_picker/file_picker_impl.dart'; import 'package:appflowy/util/file_picker/file_picker_service.dart'; import 'package:appflowy/plugins/document/application/prelude.dart'; -import 'package:appflowy/workspace/application/settings/settings_location_cubit.dart'; import 'package:appflowy/workspace/application/user/prelude.dart'; import 'package:appflowy/workspace/application/workspace/prelude.dart'; import 'package:appflowy/workspace/application/edit_panel/edit_panel_bloc.dart'; @@ -32,26 +32,35 @@ import 'package:get_it/get_it.dart'; import 'package:http/http.dart' as http; class DependencyResolver { - static Future resolve(GetIt getIt) async { + static Future resolve( + GetIt getIt, + IntegrationMode mode, + ) async { _resolveUserDeps(getIt); - _resolveHomeDeps(getIt); - _resolveFolderDeps(getIt); - _resolveDocDeps(getIt); - _resolveGridDeps(getIt); - - _resolveCommonService(getIt); + _resolveCommonService(getIt, mode); } } -void _resolveCommonService(GetIt getIt) async { +void _resolveCommonService( + GetIt getIt, + IntegrationMode mode, +) async { // getIt.registerFactory(() => RustKeyValue()); getIt.registerFactory(() => DartKeyValue()); getIt.registerFactory(() => FilePicker()); - getIt.registerFactory(() => ApplicationDataStorage()); + if (mode.isTest) { + getIt.registerFactory( + () => MockApplicationDataStorage(), + ); + } else { + getIt.registerFactory( + () => ApplicationDataStorage(), + ); + } getIt.registerFactoryAsync( () async { diff --git a/frontend/appflowy_flutter/lib/startup/startup.dart b/frontend/appflowy_flutter/lib/startup/startup.dart index 32199e6154..d31544a4c7 100644 --- a/frontend/appflowy_flutter/lib/startup/startup.dart +++ b/frontend/appflowy_flutter/lib/startup/startup.dart @@ -1,7 +1,7 @@ import 'dart:io'; import 'package:appflowy/env/env.dart'; -import 'package:appflowy/workspace/application/settings/settings_location_cubit.dart'; +import 'package:appflowy/workspace/application/settings/prelude.dart'; import 'package:appflowy_backend/appflowy_backend.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -18,8 +18,14 @@ abstract class EntryPoint { Widget create(LaunchConfiguration config); } +class FlowyRunnerContext { + final Directory applicationDataDirectory; + + FlowyRunnerContext({required this.applicationDataDirectory}); +} + class FlowyRunner { - static Future run( + static Future run( EntryPoint f, IntegrationMode mode, { LaunchConfiguration config = const LaunchConfiguration( @@ -32,11 +38,10 @@ class FlowyRunner { // Specify the env initGetIt(getIt, mode, f, config); - final directory = await getIt() - .getPath() - .then((value) => Directory(value)); - - // final directory = await appFlowyDocumentDirectory(); + final applicationDataDirectory = + await getIt().getPath().then( + (value) => Directory(value), + ); // add task final launcher = getIt(); @@ -49,13 +54,13 @@ class FlowyRunner { // init the app window const InitAppWindowTask(), // Init Rust SDK - InitRustSDKTask(directory: directory), + InitRustSDKTask(directory: applicationDataDirectory), // Load Plugins, like document, grid ... const PluginLoadTask(), // init the app widget // ignore in test mode - if (!mode.isTest()) ...[ + if (!mode.isUnitTest) ...[ const HotKeyTask(), InitSupabaseTask( url: Env.supabaseUrl, @@ -70,6 +75,10 @@ class FlowyRunner { ], ); await launcher.launch(); // execute the tasks + + return FlowyRunnerContext( + applicationDataDirectory: applicationDataDirectory, + ); } } @@ -94,7 +103,7 @@ Future initGetIt( ); getIt.registerSingleton(PluginSandbox()); - await DependencyResolver.resolve(getIt); + await DependencyResolver.resolve(getIt, env); } class LaunchContext { @@ -145,23 +154,24 @@ class AppLauncher { enum IntegrationMode { develop, release, - test, - integrationTest, -} + unitTest, + integrationTest; -extension IntegrationEnvExt on IntegrationMode { - bool isTest() { - return this == IntegrationMode.test; - } + // test mode + bool get isTest => isUnitTest || isIntegrationTest; + bool get isUnitTest => this == IntegrationMode.unitTest; + bool get isIntegrationTest => this == IntegrationMode.integrationTest; - bool isIntegrationTest() { - return this == IntegrationMode.integrationTest; - } + // release mode + bool get isRelease => this == IntegrationMode.release; + + // develop mode + bool get isDevelop => this == IntegrationMode.develop; } IntegrationMode integrationEnv() { if (Platform.environment.containsKey('FLUTTER_TEST')) { - return IntegrationMode.test; + return IntegrationMode.unitTest; } if (kReleaseMode) { diff --git a/frontend/appflowy_flutter/lib/startup/tasks/localization.dart b/frontend/appflowy_flutter/lib/startup/tasks/localization.dart index 8a28a2ded1..1fcb3eb660 100644 --- a/frontend/appflowy_flutter/lib/startup/tasks/localization.dart +++ b/frontend/appflowy_flutter/lib/startup/tasks/localization.dart @@ -8,5 +8,6 @@ class InitLocalizationTask extends LaunchTask { @override Future initialize(LaunchContext context) async { await EasyLocalization.ensureInitialized(); + EasyLocalization.logger.enableBuildModes = []; } } diff --git a/frontend/appflowy_flutter/lib/startup/tasks/rust_sdk.dart b/frontend/appflowy_flutter/lib/startup/tasks/rust_sdk.dart index d1e99f0d94..da2575343d 100644 --- a/frontend/appflowy_flutter/lib/startup/tasks/rust_sdk.dart +++ b/frontend/appflowy_flutter/lib/startup/tasks/rust_sdk.dart @@ -38,7 +38,7 @@ AppFlowyEnv getAppFlowyEnv() { final collabTableConfig = CollabTableConfig(enable: true, table_name: Env.supabaseCollabTable); - final supbaseDBConfig = SupabaseDBConfig( + final supabaseDBConfig = SupabaseDBConfig( url: Env.supabaseUrl, key: Env.supabaseKey, jwt_secret: Env.supabaseJwtSecret, @@ -47,7 +47,7 @@ AppFlowyEnv getAppFlowyEnv() { return AppFlowyEnv( supabase_config: supabaseConfig, - supabase_db_config: supbaseDBConfig, + supabase_db_config: supabaseDBConfig, ); } @@ -62,7 +62,7 @@ Future appFlowyApplicationDataDirectory() async { case IntegrationMode.release: final Directory documentsDir = await getApplicationSupportDirectory(); return Directory(path.join(documentsDir.path, 'data')).create(); - case IntegrationMode.test: + case IntegrationMode.unitTest: case IntegrationMode.integrationTest: return Directory(path.join(Directory.current.path, '.sandbox')); } diff --git a/frontend/appflowy_flutter/lib/startup/tasks/windows.dart b/frontend/appflowy_flutter/lib/startup/tasks/windows.dart index 0dec1377fd..c2d044e631 100644 --- a/frontend/appflowy_flutter/lib/startup/tasks/windows.dart +++ b/frontend/appflowy_flutter/lib/startup/tasks/windows.dart @@ -27,7 +27,7 @@ class InitAppWindowTask extends LaunchTask with WindowListener { windowManager.addListener(this); Size windowSize = await WindowSizeManager().getSize(); - if (context.env.isIntegrationTest()) { + if (context.env.isIntegrationTest) { windowSize = const Size(1600, 1200); } diff --git a/frontend/appflowy_flutter/lib/user/presentation/folder/folder_widget.dart b/frontend/appflowy_flutter/lib/user/presentation/folder/folder_widget.dart index f495a79a3a..8ffde1c971 100644 --- a/frontend/appflowy_flutter/lib/user/presentation/folder/folder_widget.dart +++ b/frontend/appflowy_flutter/lib/user/presentation/folder/folder_widget.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:appflowy/util/file_picker/file_picker_service.dart'; +import 'package:appflowy/workspace/application/settings/prelude.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/size.dart'; @@ -12,7 +13,6 @@ import 'package:google_fonts/google_fonts.dart'; import '../../../generated/locale_keys.g.dart'; import '../../../startup/startup.dart'; -import '../../../workspace/application/settings/settings_location_cubit.dart'; import '../../../workspace/presentation/home/toast.dart'; enum _FolderPage { diff --git a/frontend/appflowy_flutter/lib/workspace/application/appearance.dart b/frontend/appflowy_flutter/lib/workspace/application/appearance.dart index 6bae98aa25..e669e31add 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/appearance.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/appearance.dart @@ -53,7 +53,7 @@ class AppearanceSettingsCubit extends Cubit { /// changed. Fallback to [en] locale if [newLocale] is not supported. void setLocale(BuildContext context, Locale newLocale) { if (!context.supportedLocales.contains(newLocale)) { - Log.warn("Unsupported locale: $newLocale, Fallback to locale: en"); + // Log.warn("Unsupported locale: $newLocale, Fallback to locale: en"); newLocale = const Locale('en'); } diff --git a/frontend/appflowy_flutter/lib/workspace/application/settings/application_data_storage.dart b/frontend/appflowy_flutter/lib/workspace/application/settings/application_data_storage.dart new file mode 100644 index 0000000000..39f95695ae --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/application/settings/application_data_storage.dart @@ -0,0 +1,105 @@ +import 'dart:io'; + +import 'package:appflowy/core/config/kv.dart'; +import 'package:appflowy/core/config/kv_keys.dart'; +import 'package:appflowy/startup/startup.dart'; +import 'package:appflowy_backend/log.dart'; +import 'package:flutter/foundation.dart'; +import 'package:path/path.dart' as p; + +import '../../../startup/tasks/prelude.dart'; + +const appFlowyDataFolder = "AppFlowyDataDoNotRename"; + +class ApplicationDataStorage { + ApplicationDataStorage(); + String? _cachePath; + + /// Set the custom path to store the data. + /// If the path is not exists, the path will be created. + /// If the path is invalid, the path will be set to the default path. + Future setCustomPath(String path) async { + if (kIsWeb || Platform.isAndroid || Platform.isIOS) { + Log.info('LocalFileStorage is not supported on this platform.'); + return; + } + + if (Platform.isMacOS) { + // remove the prefix `/Volumes/*` + path = path.replaceFirst(RegExp(r'^/Volumes/[^/]+'), ''); + } else if (Platform.isWindows) { + path = path.replaceAll('/', '\\'); + } + + // If the path is not ends with `AppFlowyData`, we will append the + // `AppFlowyData` to the path. If the path is ends with `AppFlowyData`, + // which means the path is the custom path. + if (p.basename(path) != appFlowyDataFolder) { + path = p.join(path, appFlowyDataFolder); + } + + // create the directory if not exists. + final directory = Directory(path); + if (!directory.existsSync()) { + await directory.create(recursive: true); + } + + setPath(path); + } + + Future setPath(String path) async { + if (kIsWeb || Platform.isAndroid || Platform.isIOS) { + Log.info('LocalFileStorage is not supported on this platform.'); + return; + } + + await getIt().set(KVKeys.pathLocation, path); + // clear the cache path, and not set the cache path to the new path because the set path may be invalid + _cachePath = null; + } + + Future getPath() async { + if (_cachePath != null) { + return _cachePath!; + } + + final response = await getIt().get(KVKeys.pathLocation); + String path = await response.fold( + (error) async { + // return the default path if the path is not set + final directory = await appFlowyApplicationDataDirectory(); + return directory.path; + }, + (path) => path, + ); + _cachePath = path; + + // if the path is not exists means the path is invalid, so we should clear the kv store + if (!Directory(path).existsSync()) { + await getIt().clear(); + final directory = await appFlowyApplicationDataDirectory(); + path = directory.path; + } + + return path; + } +} + +class MockApplicationDataStorage extends ApplicationDataStorage { + MockApplicationDataStorage(); + + // this value will be clear after setup + // only for the initial step + @visibleForTesting + static String? initialPath; + + @override + Future getPath() async { + final path = initialPath; + if (path != null) { + initialPath = null; + return Future.value(path); + } + return super.getPath(); + } +} diff --git a/frontend/appflowy_flutter/lib/workspace/application/settings/prelude.dart b/frontend/appflowy_flutter/lib/workspace/application/settings/prelude.dart index 3917b54aaf..e2923d42a2 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/settings/prelude.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/settings/prelude.dart @@ -1 +1,2 @@ export 'settings_dialog_bloc.dart'; +export 'application_data_storage.dart'; diff --git a/frontend/appflowy_flutter/lib/workspace/application/settings/settings_location_cubit.dart b/frontend/appflowy_flutter/lib/workspace/application/settings/settings_location_cubit.dart index 8c8feadcb1..e676e88a76 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/settings/settings_location_cubit.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/settings/settings_location_cubit.dart @@ -1,13 +1,8 @@ -import 'dart:io'; - -import 'package:appflowy/core/config/kv.dart'; -import 'package:appflowy/core/config/kv_keys.dart'; import 'package:appflowy/startup/startup.dart'; -import 'package:appflowy_backend/log.dart'; +import 'package:appflowy/workspace/application/settings/application_data_storage.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:path/path.dart' as p; import '../../../startup/tasks/prelude.dart'; @@ -27,7 +22,7 @@ class SettingsLocationCubit extends Cubit { Future resetDataStoragePathToApplicationDefault() async { final directory = await appFlowyApplicationDataDirectory(); - await getIt()._setPath(directory.path); + await getIt().setPath(directory.path); emit(SettingsLocationState.didReceivedPath(directory.path)); } @@ -41,79 +36,3 @@ class SettingsLocationCubit extends Cubit { emit(SettingsLocationState.didReceivedPath(path)); } } - -const appFlowyDataFolder = "AppFlowyDataDoNotRename"; - -class ApplicationDataStorage { - ApplicationDataStorage(); - String? _cachePath; - - /// Set the custom path to store the data. - /// If the path is not exists, the path will be created. - /// If the path is invalid, the path will be set to the default path. - Future setCustomPath(String path) async { - if (kIsWeb || Platform.isAndroid || Platform.isIOS) { - Log.info('LocalFileStorage is not supported on this platform.'); - return; - } - - if (Platform.isMacOS) { - // remove the prefix `/Volumes/*` - path = path.replaceFirst(RegExp(r'^/Volumes/[^/]+'), ''); - } else if (Platform.isWindows) { - path = path.replaceAll('/', '\\'); - } - - // If the path is not ends with `AppFlowyData`, we will append the - // `AppFlowyData` to the path. If the path is ends with `AppFlowyData`, - // which means the path is the custom path. - if (p.basename(path) != appFlowyDataFolder) { - path = p.join(path, appFlowyDataFolder); - } - - // create the directory if not exists. - final directory = Directory(path); - if (!directory.existsSync()) { - await directory.create(recursive: true); - } - - _setPath(path); - } - - Future _setPath(String path) async { - if (kIsWeb || Platform.isAndroid || Platform.isIOS) { - Log.info('LocalFileStorage is not supported on this platform.'); - return; - } - - await getIt().set(KVKeys.pathLocation, path); - // clear the cache path, and not set the cache path to the new path because the set path may be invalid - _cachePath = null; - } - - Future getPath() async { - if (_cachePath != null) { - return _cachePath!; - } - - final response = await getIt().get(KVKeys.pathLocation); - String path = await response.fold( - (error) async { - // return the default path if the path is not set - final directory = await appFlowyApplicationDataDirectory(); - return directory.path; - }, - (path) => path, - ); - _cachePath = path; - - // if the path is not exists means the path is invalid, so we should clear the kv store - if (!Directory(path).existsSync()) { - await getIt().clear(); - final directory = await appFlowyApplicationDataDirectory(); - path = directory.path; - } - - return path; - } -} diff --git a/frontend/appflowy_flutter/test/util.dart b/frontend/appflowy_flutter/test/util.dart index 137613cddd..0b86a9c331 100644 --- a/frontend/appflowy_flutter/test/util.dart +++ b/frontend/appflowy_flutter/test/util.dart @@ -36,7 +36,7 @@ class AppFlowyUnitTest { await FlowyRunner.run( FlowyTestApp(), - IntegrationMode.test, + IntegrationMode.unitTest, ); final test = AppFlowyUnitTest();