fix: windows callback (#4006)

* tests: fix supabase integration test

* ci: fix

* chore: fix windows callback
This commit is contained in:
Nathan.fooo 2023-11-25 01:18:31 -08:00 committed by GitHub
parent 29a6eab1ce
commit b3dd5fb8bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 189 additions and 55 deletions

View File

@ -300,6 +300,14 @@ jobs:
- name: Uncompress appflowy_flutter
run: tar -xf appflowy_flutter.tar.gz
# - name: Create .env.cloud.test file in flowy-server
# working-directory: frontend/appflowy_flutter
# run: |
# touch .env.cloud.test
# echo SUPABASE_URL=${{ secrets.SUPABASE_URL }} >> .env.cloud.test
# echo SUPABASE_ANON_KEY=${{ secrets.SUPABASE_ANON_KEY }} >> .env.cloud.test
# echo APPFLOWY_CLOUD_URL=${{ secrets.APPFLOWY_CLOUD_URL }} >> .env.cloud.test
- name: Run flutter pub get
working-directory: frontend
run: cargo make pub_get

View File

@ -0,0 +1,20 @@
# Only used for integration test
# Cloud Type Configuration
# Use this configuration file to specify the cloud type and its associated settings. The available cloud types are:
# Local: 0
# Supabase: 1
# AppFlowy Cloud: 2
# By default, it's set to Local.
CLOUD_TYPE=1
# Supabase Configuration
# If using Supabase (CLOUD_TYPE=1), provide the following details:
SUPABASE_URL=
SUPABASE_ANON_KEY=
# AppFlowy Cloud Configuration
# If using Supabase (CLOUD_TYPE=2), provide the following details:
#
# When using localhost for development. you can use the following settings:
APPFLOWY_CLOUD_URL=

View File

@ -1,3 +1,4 @@
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/workspace/application/settings/prelude.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart';
@ -11,13 +12,13 @@ void main() {
group('auth', () {
testWidgets('sign in with supabase', (tester) async {
await tester.initializeAppFlowy();
await tester.initializeAppFlowy(cloudType: CloudType.supabase);
await tester.tapGoogleLoginInButton();
tester.expectToSeeHomePage();
});
testWidgets('sign out with supabase', (tester) async {
await tester.initializeAppFlowy();
await tester.initializeAppFlowy(cloudType: CloudType.supabase);
await tester.tapGoogleLoginInButton();
// Open the setting page and sign out
@ -34,36 +35,37 @@ void main() {
});
testWidgets('sign in as annoymous', (tester) async {
await tester.initializeAppFlowy();
await tester.initializeAppFlowy(cloudType: CloudType.supabase);
await tester.tapSignInAsGuest();
// should not see the sync setting page when sign in as annoymous
await tester.openSettings();
await tester.expectNoSettingsPage(SettingsPage.cloud);
await tester.openSettingsPage(SettingsPage.user);
tester.expectToSeeGoogleLoginButton();
});
testWidgets('enable encryption', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoogleLoginInButton();
// testWidgets('enable encryption', (tester) async {
// await tester.initializeAppFlowy(cloudType: CloudType.supabase);
// await tester.tapGoogleLoginInButton();
// Open the setting page and sign out
await tester.openSettings();
await tester.openSettingsPage(SettingsPage.cloud);
// // Open the setting page and sign out
// await tester.openSettings();
// await tester.openSettingsPage(SettingsPage.cloud);
// the switch should be off by default
tester.assertEnableEncryptSwitchValue(false);
await tester.toggleEnableEncrypt();
// // the switch should be off by default
// tester.assertEnableEncryptSwitchValue(false);
// await tester.toggleEnableEncrypt();
// the switch should be on after toggling
tester.assertEnableEncryptSwitchValue(true);
// // the switch should be on after toggling
// tester.assertEnableEncryptSwitchValue(true);
// the switch can not be toggled back to off
await tester.toggleEnableEncrypt();
tester.assertEnableEncryptSwitchValue(true);
});
// // the switch can not be toggled back to off
// await tester.toggleEnableEncrypt();
// tester.assertEnableEncryptSwitchValue(true);
// });
testWidgets('enable sync', (tester) async {
await tester.initializeAppFlowy();
await tester.initializeAppFlowy(cloudType: CloudType.supabase);
await tester.tapGoogleLoginInButton();
// Open the setting page and sign out

View File

@ -22,6 +22,7 @@ import 'share_markdown_test.dart' as share_markdown_test;
import 'sidebar/sidebar_test_runner.dart' as sidebar_test_runner;
import 'switch_folder_test.dart' as switch_folder_test;
import 'tabs_test.dart' as tabs_test;
// import 'auth/supabase_auth_test.dart' as supabase_auth_test_runner;
/// The main task runner for all integration tests in AppFlowy.
///
@ -74,10 +75,7 @@ Future<void> main() async {
// User settings
settings_test_runner.main();
// final cloudType = await getCloudType();
// if (cloudType == CloudType.supabase) {
// auth_test_runner.main();
// }
// supabase_auth_test_runner.main();
// board_test.main();
// empty_document_test.main();

View File

@ -1,12 +1,14 @@
import 'dart:async';
import 'dart:io';
import 'package:appflowy/env/env.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/env/cloud_env_test.dart';
import 'package:appflowy/startup/entry_point.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/presentation/presentation.dart';
import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart';
import 'package:appflowy/workspace/application/settings/prelude.dart';
import 'package:dartz/dartz.dart';
import 'package:flowy_infra/uuid.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/gestures.dart';
@ -29,6 +31,7 @@ extension AppFlowyTestBase on WidgetTester {
// use to append after the application data directory
String? pathExtension,
Size windowsSize = const Size(1600, 1200),
CloudType? cloudType,
}) async {
binding.setSurfaceSize(windowsSize);
@ -38,13 +41,28 @@ extension AppFlowyTestBase on WidgetTester {
);
WidgetsFlutterBinding.ensureInitialized();
await FlowyRunner.run(
FlowyApp(),
IntegrationMode.integrationTest,
didInitGetIt: Future(
() async {
if (cloudType != null) {
switch (cloudType) {
case CloudType.local:
break;
case CloudType.supabase:
await useSupabaseCloud();
break;
case CloudType.appflowyCloud:
await useAppFlowyCloud();
break;
}
}
},
),
);
await waitUntilSignInPageShow();
return FlowyTestContext(
applicationDataDirectory: directory,
);
@ -207,3 +225,16 @@ extension AppFlowyFinderTestBase on CommonFinders {
);
}
}
Future<void> useSupabaseCloud() async {
await setCloudType(CloudType.supabase);
await setSupbaseServer(
Some(TestEnv.supabaseUrl),
Some(TestEnv.supabaseAnonKey),
);
}
Future<void> useAppFlowyCloud() async {
await setCloudType(CloudType.appflowyCloud);
await setAppFlowyCloudUrl(Some(TestEnv.afCloudUrl));
}

View File

@ -142,13 +142,26 @@ enum CloudType {
return 2;
}
}
static fromValue(int value) {
switch (value) {
case 0:
return CloudType.local;
case 1:
return CloudType.supabase;
case 2:
return CloudType.appflowyCloud;
default:
return CloudType.local;
}
}
}
CloudType currentCloudType() {
return getIt<AppFlowyCloudSharedEnv>().cloudType;
}
Future<void> setAppFlowyCloudBaseUrl(Option<String> url) async {
Future<void> setAppFlowyCloudUrl(Option<String> url) async {
await url.fold(
() => getIt<KeyValueStorage>().remove(KVKeys.kAppflowyCloudBaseURL),
(s) => getIt<KeyValueStorage>().set(KVKeys.kAppflowyCloudBaseURL, s),

View File

@ -0,0 +1,38 @@
// lib/env/env.dart
import 'package:envied/envied.dart';
part 'cloud_env_test.g.dart';
/// Follow the guide on https://supabase.com/docs/guides/auth/social-login/auth-google to setup the auth provider.
///
@Envied(path: '.env.cloud.test')
abstract class TestEnv {
@EnviedField(
obfuscate: true,
varName: 'CLOUD_TYPE',
defaultValue: '0',
)
static final int cloudType = _TestEnv.cloudType;
/// AppFlowy Cloud Configuration
@EnviedField(
obfuscate: true,
varName: 'APPFLOWY_CLOUD_URL',
defaultValue: '',
)
static final String afCloudUrl = _TestEnv.afCloudUrl;
// Supabase Configuration:
@EnviedField(
obfuscate: true,
varName: 'SUPABASE_URL',
defaultValue: '',
)
static final String supabaseUrl = _TestEnv.supabaseUrl;
@EnviedField(
obfuscate: true,
varName: 'SUPABASE_ANON_KEY',
defaultValue: '',
)
static final String supabaseAnonKey = _TestEnv.supabaseAnonKey;
}

View File

@ -1,4 +1,4 @@
import 'package:appflowy/env/env.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/workspace/application/user/prelude.dart';

View File

@ -1,6 +1,6 @@
import 'package:appflowy/core/config/kv.dart';
import 'package:appflowy/core/network_monitor.dart';
import 'package:appflowy/env/env.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/mobile/application/mobile_router.dart';
import 'package:appflowy/plugins/document/application/prelude.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/clipboard_service.dart';

View File

@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:io';
import 'package:appflowy/workspace/application/settings/prelude.dart';
@ -37,6 +38,7 @@ class FlowyRunner {
static Future<FlowyRunnerContext> run(
EntryPoint f,
IntegrationMode mode, {
Future? didInitGetIt,
LaunchConfiguration config = const LaunchConfiguration(
autoRegistrationSupported: false,
),
@ -47,6 +49,8 @@ class FlowyRunner {
// Specify the env
await initGetIt(getIt, mode, f, config);
await didInitGetIt;
final applicationDataDirectory =
await getIt<ApplicationDataStorage>().getPath().then(
(value) => Directory(value),

View File

@ -1,7 +1,11 @@
import 'package:appflowy/env/env.dart';
import 'dart:io';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/startup/tasks/supabase_task.dart';
import 'package:appflowy/user/application/user_auth_listener.dart';
import 'package:appflowy_backend/log.dart';
import 'package:url_protocol/url_protocol.dart';
class InitAppFlowyCloudTask extends LaunchTask {
UserAuthStateListener? _authStateListener;
@ -25,6 +29,11 @@ class InitAppFlowyCloudTask extends LaunchTask {
}
},
);
if (Platform.isWindows) {
// register deep link for Windows
registerProtocolHandler(appflowyDeepLinkSchema);
}
}
@override

View File

@ -2,7 +2,7 @@ import 'dart:convert';
import 'dart:io';
import 'package:appflowy/env/backend_env.dart';
import 'package:appflowy/env/env.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/user/application/auth/device_id.dart';
import 'package:appflowy_backend/appflowy_backend.dart';
import 'package:path_provider/path_provider.dart';

View File

@ -1,7 +1,7 @@
import 'dart:async';
import 'dart:io';
import 'package:appflowy/env/env.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/user/application/supabase_realtime.dart';
import 'package:appflowy/workspace/application/settings/application_data_storage.dart';
import 'package:flutter/foundation.dart';

View File

@ -8,7 +8,6 @@ import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
import 'package:dartz/dartz.dart';
import 'package:nanoid/nanoid.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'auth_error.dart';
@ -16,6 +15,7 @@ import 'auth_error.dart';
/// Only used for testing.
class MockAuthService implements AuthService {
MockAuthService();
static OauthSignInPB? signInPayload;
SupabaseClient get _client => Supabase.instance.client;
GoTrueClient get _auth => _client.auth;
@ -47,15 +47,25 @@ class MockAuthService implements AuthService {
required String platform,
Map<String, String> params = const {},
}) async {
const password = "AppFlowyTest123!";
const email = "supabase_integration_test@appflowy.io";
try {
final response = await _auth.signUp(
email: "${nanoid(10)}@appflowy.io",
password: "AppFlowyTest123!",
);
final uuid = response.user!.id;
final email = response.user!.email!;
if (_auth.currentSession == null) {
try {
await _auth.signInWithPassword(
password: password,
email: email,
);
} catch (e) {
Log.error(e);
return Left(AuthError.supabaseSignUpError);
}
}
// Check if the user is already logged in.
final session = _auth.currentSession!;
final uuid = session.user.id;
// Create the OAuth sign-in payload.
final payload = OauthSignInPB(
authType: AuthTypePB.Supabase,
map: {
@ -65,6 +75,7 @@ class MockAuthService implements AuthService {
},
);
// Send the sign-in event and handle the response.
return UserEventOauthSignIn(payload).send().then((value) => value.swap());
} on AuthException catch (e) {
Log.error(e);
@ -74,7 +85,7 @@ class MockAuthService implements AuthService {
@override
Future<void> signOut() async {
await _auth.signOut();
// await _auth.signOut();
await _appFlowyAuthService.signOut();
}

View File

@ -1,5 +1,5 @@
import 'package:appflowy/core/frameless_window.dart';
import 'package:appflowy/env/env.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart';
import 'package:appflowy/user/presentation/widgets/widgets.dart';

View File

@ -1,4 +1,4 @@
import 'package:appflowy/env/env.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart';

View File

@ -1,4 +1,4 @@
import 'package:appflowy/env/env.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/auth/auth_service.dart';

View File

@ -1,5 +1,5 @@
import 'package:appflowy/env/backend_env.dart';
import 'package:appflowy/env/env.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:easy_localization/easy_localization.dart';
@ -27,15 +27,15 @@ class AppFlowyCloudURLsBloc
restartApp: true,
),
);
await setAppFlowyCloudBaseUrl(none());
await setAppFlowyCloudUrl(none());
} else {
validateUrl(state.updatedServerUrl).fold(
(error) => emit(state.copyWith(urlError: Some(error))),
(_) async {
if (state.config.base_url != state.updatedServerUrl) {
await setAppFlowyCloudBaseUrl(Some(state.updatedServerUrl));
add(const AppFlowyCloudURLsEvent.didSaveConfig());
await setAppFlowyCloudUrl(Some(state.updatedServerUrl));
}
add(const AppFlowyCloudURLsEvent.didSaveConfig());
},
);
}

View File

@ -1,4 +1,4 @@
import 'package:appflowy/env/env.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

View File

@ -1,5 +1,5 @@
import 'package:appflowy/env/backend_env.dart';
import 'package:appflowy/env/env.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/plugins/database_view/application/defines.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy_backend/dispatch/dispatch.dart';

View File

@ -1,5 +1,5 @@
import 'package:appflowy/env/backend_env.dart';
import 'package:appflowy/env/env.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy_backend/dispatch/dispatch.dart';

View File

@ -1,4 +1,4 @@
import 'package:appflowy/env/env.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/workspace/application/settings/cloud_setting_bloc.dart';

View File

@ -1,4 +1,4 @@
import 'package:appflowy/env/env.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/sign_in_bloc.dart';

View File

@ -1,7 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'package:appflowy/env/env.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/startup/startup.dart';