diff --git a/commet/integration_test/matrix/create_space_test.dart b/commet/integration_test/matrix/create_space_test.dart new file mode 100644 index 000000000..1526db8e6 --- /dev/null +++ b/commet/integration_test/matrix/create_space_test.dart @@ -0,0 +1,130 @@ +import 'package:commet/client/room.dart'; +import 'package:commet/generated/l10n.dart'; +import 'package:commet/ui/molecules/space_selector.dart'; +import 'package:commet/ui/pages/login/login_page.dart'; +import 'package:commet/utils/rng.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:commet/main.dart'; +import 'package:hive/hive.dart'; +import 'package:integration_test/integration_test.dart'; + +import '../extensions/wait_for.dart'; +import '../extensions/common_flows.dart'; +import 'package:tiamat/tiamat.dart' as tiamat; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('Create Private Space', (WidgetTester tester) async { + await tester.clearUserData(); + + var app = App(); + await _openMenu(tester, app); + await _setPrivate(tester); + + String spaceName = "Private Space ${RandomUtils.getRandomString(8)}"; + await _setSpaceName(tester, spaceName); + await _confirmCreateSpace(tester); + + var client = app.clientManager.getClients().first; + + expect(client.spaces.any((element) => element.displayName == spaceName), + isTrue); + expect( + client.spaces + .firstWhere((element) => element.displayName == spaceName) + .visibility, + equals(RoomVisibility.invite)); + + await app.clientManager.close(); + await tester.clean(); + }); + + testWidgets('Create Public Space', (WidgetTester tester) async { + await tester.clearUserData(); + + var app = App(); + await _openMenu(tester, app); + await _setPublic(tester); + + String spaceName = "Public Space ${RandomUtils.getRandomString(8)}"; + await _setSpaceName(tester, spaceName); + await _confirmCreateSpace(tester); + + var client = app.clientManager.getClients().first; + + expect(client.spaces.any((element) => element.displayName == spaceName), + isTrue); + expect( + client.spaces + .firstWhere((element) => element.displayName == spaceName) + .visibility, + equals(RoomVisibility.public)); + + await app.clientManager.close(); + await tester.clean(); + }); +} + +Future _confirmCreateSpace(WidgetTester tester) async { + await tester.tap(find + .widgetWithText(tiamat.Button, T.current.addSpaceViewCreateSpaceButton) + .first); + + await tester.pumpAndSettle(); +} + +Future _setSpaceName(WidgetTester tester, String spaceName) async { + await tester.enterText( + find.widgetWithText( + tiamat.TextInput, + T.current.spaceNamePrompt, + ), + spaceName); +} + +Future _setPrivate(WidgetTester tester) async { + await tester.tap(find.byType(tiamat.DropdownSelector)); + + await tester.pumpAndSettle(); + + await tester.tap(find + .widgetWithText(tiamat.Text, T.current.roomVisibilityPrivateExplanation) + .last); + + await tester.pumpAndSettle(); +} + +Future _setPublic(WidgetTester tester) async { + await tester.tap(find.byType(tiamat.DropdownSelector)); + + await tester.pumpAndSettle(); + + await tester.tap(find + .widgetWithText(tiamat.Text, T.current.roomVisibilityPublicExplanation) + .last); + + await tester.pumpAndSettle(); +} + +Future _openMenu(WidgetTester tester, App app) async { + await tester.pumpWidget(app); + + await tester.login(app); + + await tester.pumpAndSettle(); + + await tester.dragUntilVisible( + find.widgetWithIcon(tiamat.ImageButton, Icons.add), + find.byType(SpaceSelector), + Offset(0, 50)); + + await tester.tap(find.widgetWithIcon(tiamat.ImageButton, Icons.add)); + + await tester.pumpAndSettle(); + + await tester.tap(find.widgetWithText(InkWell, T.current.createNewSpace)); + + await tester.pumpAndSettle(); +} diff --git a/commet/integration_test/runner.dart b/commet/integration_test/runner.dart index 8cfd7ac93..a29721cf1 100644 --- a/commet/integration_test/runner.dart +++ b/commet/integration_test/runner.dart @@ -3,10 +3,12 @@ import 'package:integration_test/integration_test.dart'; import 'matrix/login_test.dart' as login_test; import 'matrix/key_verification_test.dart' as key_verification_test; +import 'matrix/create_space_test.dart' as create_space_test; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); login_test.main(); key_verification_test.main(); + create_space_test.main(); } diff --git a/commet/lib/client/matrix/matrix_space.dart b/commet/lib/client/matrix/matrix_space.dart index 3ad85a56b..320a277ac 100644 --- a/commet/lib/client/matrix/matrix_space.dart +++ b/commet/lib/client/matrix/matrix_space.dart @@ -17,10 +17,20 @@ class MatrixSpace extends Space { String get topic => _matrixRoom.topic; @override - RoomVisibility get visibility => - _matrixRoom.joinRules == matrix.JoinRules.public - ? RoomVisibility.public - : RoomVisibility.private; + RoomVisibility get visibility { + switch (_matrixRoom.joinRules) { + case matrix.JoinRules.public: + return RoomVisibility.public; + case matrix.JoinRules.knock: + return RoomVisibility.knock; + case matrix.JoinRules.invite: + return RoomVisibility.invite; + case matrix.JoinRules.private: + return RoomVisibility.private; + default: + return RoomVisibility.private; + } + } MatrixSpace(client, matrix.Room room, matrix.Client matrixClient) : super(room.id, client) { @@ -28,6 +38,8 @@ class MatrixSpace extends Space { _matrixClient = matrixClient; displayName = room.getLocalizedDisplayname(); + _matrixRoom.postLoad(); + room.onUpdate.stream.listen((event) { refresh(); onUpdate.add(null); diff --git a/commet/lib/client/room.dart b/commet/lib/client/room.dart index 6c5e13c76..64aa226e3 100644 --- a/commet/lib/client/room.dart +++ b/commet/lib/client/room.dart @@ -3,10 +3,7 @@ import 'package:flutter/material.dart'; import 'permissions.dart'; -enum RoomVisibility { - public, - private, -} +enum RoomVisibility { public, private, invite, knock } abstract class Room { late String identifier; @@ -23,7 +20,8 @@ abstract class Room { int notificationCount = 0; - Future sendMessage(String message, {TimelineEvent? inReplyTo}); + Future sendMessage(String message, + {TimelineEvent? inReplyTo}); Room(this.identifier, this.client) { identifier = identifier; diff --git a/commet/lib/ui/pages/add_space/add_space_view.dart b/commet/lib/ui/pages/add_space/add_space_view.dart index c20f5ea4c..8d50b74f6 100644 --- a/commet/lib/ui/pages/add_space/add_space_view.dart +++ b/commet/lib/ui/pages/add_space/add_space_view.dart @@ -51,9 +51,15 @@ Widget wbAddSpacePageSingleAccount(BuildContext context) { } class AddSpaceView extends StatefulWidget { - const AddSpaceView({super.key, required this.clients, this.onCreateSpace, this.onJoinSpace, this.initialPhase}); + const AddSpaceView( + {super.key, + required this.clients, + this.onCreateSpace, + this.onJoinSpace, + this.initialPhase}); final List clients; - final Function(Client client, String spaceName, RoomVisibility visibility)? onCreateSpace; + final Function(Client client, String spaceName, RoomVisibility visibility)? + onCreateSpace; final Function(Client client, String address)? onJoinSpace; final _AddSpacePhase? initialPhase; @@ -74,10 +80,12 @@ class _AddSpaceViewState extends State { PreviewData? spacePreview; bool loadingSpacePreview = false; - Debouncer spacePreviewDebounce = Debouncer(delay: Duration(milliseconds: 500)); + Debouncer spacePreviewDebounce = + Debouncer(delay: Duration(milliseconds: 500)); void getSpacePreview() async { - var preview = await selectedClient.getSpacePreview(spaceAddressController.text); + var preview = + await selectedClient.getSpacePreview(spaceAddressController.text); setState(() { print("Got Preview"); @@ -185,6 +193,8 @@ class _AddSpaceViewState extends State { subtitle = T.current.roomVisibilityPublicExplanation; break; case RoomVisibility.private: + case RoomVisibility.invite: + case RoomVisibility.knock: title = T.current.roomVisibilityPrivate; icon = Icons.lock; subtitle = T.current.roomVisibilityPrivateExplanation; @@ -222,7 +232,8 @@ class _AddSpaceViewState extends State { padding: const EdgeInsets.fromLTRB(0, 4, 0, 4), child: tiamat.Button.success( text: T.current.addSpaceViewCreateSpaceButton, - onTap: () => widget.onCreateSpace?.call(selectedClient, nameController.text, visibility), + onTap: () => widget.onCreateSpace + ?.call(selectedClient, nameController.text, visibility), ), ) ], @@ -262,12 +273,15 @@ class _AddSpaceViewState extends State { ) : spacePreview != null ? RoomPreview(previewData: spacePreview!) - : Center(child: tiamat.Text.label(T.of(context).couldNotLoadRoomPreview)), + : Center( + child: tiamat.Text.label( + T.of(context).couldNotLoadRoomPreview)), ), tiamat.Button.success( text: T.of(context).joinSpacePrompt, onTap: () { - widget.onJoinSpace?.call(selectedClient, spaceAddressController.text); + widget.onJoinSpace + ?.call(selectedClient, spaceAddressController.text); }, ), ], @@ -284,7 +298,8 @@ class _AddSpaceViewState extends State { child: InkWell( child: Padding( padding: const EdgeInsets.all(8.0), - child: Center(child: tiamat.Text.labelEmphasised(T.current.createNewSpace)), + child: Center( + child: tiamat.Text.labelEmphasised(T.current.createNewSpace)), ), onTap: () { setState(() { @@ -303,7 +318,9 @@ class _AddSpaceViewState extends State { }, child: Padding( padding: const EdgeInsets.all(8.0), - child: Center(child: tiamat.Text.labelEmphasised(T.current.joinExistingSpace)), + child: Center( + child: + tiamat.Text.labelEmphasised(T.current.joinExistingSpace)), ), ), )