forked from eatvio/eatvio_app
test(tests): add comprehensive unit tests for various models and repositories, enhancing test coverage and ensuring correct functionality
This commit is contained in:
@@ -151,5 +151,293 @@ void main() {
|
||||
expect(result, true);
|
||||
verify(() => mockCommentsRepository.updateComment(id: 1, body: 'New text')).called(1);
|
||||
});
|
||||
|
||||
test('setReplyId - устанавливает replyId', () async {
|
||||
const mockComment = CommentModel(
|
||||
data: [],
|
||||
links: Links(first: '', last: '', prev: null, next: null),
|
||||
meta: Meta(currentPage: 1, from: null, lastPage: 1, links: [], perPage: 10, to: null, total: 0),
|
||||
);
|
||||
|
||||
when(() => mockFeedRepository.getBlogPostComments(id: any(named: 'id')))
|
||||
.thenAnswer((_) async => mockComment);
|
||||
await cubit.getComments('1', CommentSourceType.blogPost);
|
||||
|
||||
cubit.setReplyId(123);
|
||||
|
||||
final state = cubit.state as CommentsStateLoaded;
|
||||
expect(state.replyId, 123);
|
||||
});
|
||||
|
||||
test('setReplyId - устанавливает null replyId', () async {
|
||||
const mockComment = CommentModel(
|
||||
data: [],
|
||||
links: Links(first: '', last: '', prev: null, next: null),
|
||||
meta: Meta(currentPage: 1, from: null, lastPage: 1, links: [], perPage: 10, to: null, total: 0),
|
||||
);
|
||||
|
||||
when(() => mockFeedRepository.getBlogPostComments(id: any(named: 'id')))
|
||||
.thenAnswer((_) async => mockComment);
|
||||
await cubit.getComments('1', CommentSourceType.blogPost);
|
||||
|
||||
cubit.setReplyId(null);
|
||||
|
||||
final state = cubit.state as CommentsStateLoaded;
|
||||
expect(state.replyId, null);
|
||||
});
|
||||
|
||||
test('getComments - успешная загрузка комментариев для diet', () async {
|
||||
const id = '1';
|
||||
const mockComment = CommentModel(
|
||||
data: [],
|
||||
links: Links(first: '', last: '', prev: null, next: null),
|
||||
meta: Meta(currentPage: 1, from: null, lastPage: 1, links: [], perPage: 10, to: null, total: 0),
|
||||
);
|
||||
|
||||
when(() => mockFeedRepository.getDietsComments(id: id))
|
||||
.thenAnswer((_) async => mockComment);
|
||||
|
||||
await cubit.getComments(id, CommentSourceType.diet, true);
|
||||
|
||||
expect(cubit.state, isA<CommentsStateLoaded>());
|
||||
final loadedState = cubit.state as CommentsStateLoaded;
|
||||
expect(loadedState.comment, mockComment);
|
||||
});
|
||||
|
||||
test('getComments - успешная загрузка комментариев для recipe', () async {
|
||||
const id = '1';
|
||||
const mockComment = CommentModel(
|
||||
data: [],
|
||||
links: Links(first: '', last: '', prev: null, next: null),
|
||||
meta: Meta(currentPage: 1, from: null, lastPage: 1, links: [], perPage: 10, to: null, total: 0),
|
||||
);
|
||||
|
||||
when(() => mockFeedRepository.getRecipesComments(id: id))
|
||||
.thenAnswer((_) async => mockComment);
|
||||
|
||||
await cubit.getComments(id, CommentSourceType.recipe, true);
|
||||
|
||||
expect(cubit.state, isA<CommentsStateLoaded>());
|
||||
final loadedState = cubit.state as CommentsStateLoaded;
|
||||
expect(loadedState.comment, mockComment);
|
||||
});
|
||||
|
||||
test('getComments - успешная загрузка комментариев для plan', () async {
|
||||
const id = 'plan-slug';
|
||||
const mockComment = CommentModel(
|
||||
data: [],
|
||||
links: Links(first: '', last: '', prev: null, next: null),
|
||||
meta: Meta(currentPage: 1, from: null, lastPage: 1, links: [], perPage: 10, to: null, total: 0),
|
||||
);
|
||||
|
||||
when(() => mockFeedRepository.getPlansComments(slug: id))
|
||||
.thenAnswer((_) async => mockComment);
|
||||
|
||||
await cubit.getComments(id, CommentSourceType.plan, true);
|
||||
|
||||
expect(cubit.state, isA<CommentsStateLoaded>());
|
||||
final loadedState = cubit.state as CommentsStateLoaded;
|
||||
expect(loadedState.comment, mockComment);
|
||||
});
|
||||
|
||||
test('getComments - без isFirstFetch не показывает loading', () async {
|
||||
const id = '1';
|
||||
const mockComment = CommentModel(
|
||||
data: [],
|
||||
links: Links(first: '', last: '', prev: null, next: null),
|
||||
meta: Meta(currentPage: 1, from: null, lastPage: 1, links: [], perPage: 10, to: null, total: 0),
|
||||
);
|
||||
|
||||
when(() => mockFeedRepository.getBlogPostComments(id: id))
|
||||
.thenAnswer((_) async => mockComment);
|
||||
|
||||
await cubit.getComments(id, CommentSourceType.blogPost, false);
|
||||
|
||||
expect(cubit.state, isA<CommentsStateLoaded>());
|
||||
expect(cubit.state, isNot(isA<CommentsStateLoading>()));
|
||||
});
|
||||
|
||||
test('sendComment - отправка комментария для diet', () async {
|
||||
const id = '1';
|
||||
const commentText = 'Test comment';
|
||||
const mockComment = CommentModel(
|
||||
data: [],
|
||||
links: Links(first: '', last: '', prev: null, next: null),
|
||||
meta: Meta(currentPage: 1, from: null, lastPage: 1, links: [], perPage: 10, to: null, total: 0),
|
||||
);
|
||||
|
||||
when(() => mockFeedRepository.sendDietsComment(id: id, commentText: commentText, parentCommentId: null))
|
||||
.thenAnswer((_) async => {});
|
||||
when(() => mockFeedRepository.getDietsComments(id: id))
|
||||
.thenAnswer((_) async => mockComment);
|
||||
|
||||
await cubit.sendComment(
|
||||
id: id,
|
||||
commentText: commentText,
|
||||
commentSourceType: CommentSourceType.diet,
|
||||
);
|
||||
|
||||
verify(() => mockFeedRepository.sendDietsComment(id: id, commentText: commentText, parentCommentId: null)).called(1);
|
||||
verify(() => mockFeedRepository.getDietsComments(id: id)).called(1);
|
||||
});
|
||||
|
||||
test('sendComment - отправка комментария для recipe', () async {
|
||||
const id = '1';
|
||||
const commentText = 'Test comment';
|
||||
const mockComment = CommentModel(
|
||||
data: [],
|
||||
links: Links(first: '', last: '', prev: null, next: null),
|
||||
meta: Meta(currentPage: 1, from: null, lastPage: 1, links: [], perPage: 10, to: null, total: 0),
|
||||
);
|
||||
|
||||
when(() => mockFeedRepository.sendRecipesComment(id: id, commentText: commentText, parentCommentId: null))
|
||||
.thenAnswer((_) async => {});
|
||||
when(() => mockFeedRepository.getRecipesComments(id: id))
|
||||
.thenAnswer((_) async => mockComment);
|
||||
|
||||
await cubit.sendComment(
|
||||
id: id,
|
||||
commentText: commentText,
|
||||
commentSourceType: CommentSourceType.recipe,
|
||||
);
|
||||
|
||||
verify(() => mockFeedRepository.sendRecipesComment(id: id, commentText: commentText, parentCommentId: null)).called(1);
|
||||
verify(() => mockFeedRepository.getRecipesComments(id: id)).called(1);
|
||||
});
|
||||
|
||||
test('sendComment - отправка комментария для plan', () async {
|
||||
const id = 'plan-slug';
|
||||
const commentText = 'Test comment';
|
||||
const mockComment = CommentModel(
|
||||
data: [],
|
||||
links: Links(first: '', last: '', prev: null, next: null),
|
||||
meta: Meta(currentPage: 1, from: null, lastPage: 1, links: [], perPage: 10, to: null, total: 0),
|
||||
);
|
||||
|
||||
when(() => mockFeedRepository.sendPlansComment(slug: id, commentText: commentText, parentCommentId: null))
|
||||
.thenAnswer((_) async => {});
|
||||
when(() => mockFeedRepository.getPlansComments(slug: id))
|
||||
.thenAnswer((_) async => mockComment);
|
||||
|
||||
await cubit.sendComment(
|
||||
id: id,
|
||||
commentText: commentText,
|
||||
commentSourceType: CommentSourceType.plan,
|
||||
);
|
||||
|
||||
verify(() => mockFeedRepository.sendPlansComment(slug: id, commentText: commentText, parentCommentId: null)).called(1);
|
||||
verify(() => mockFeedRepository.getPlansComments(slug: id)).called(1);
|
||||
});
|
||||
|
||||
test('sendComment - отправка комментария с parentCommentId', () async {
|
||||
const id = '1';
|
||||
const commentText = 'Reply comment';
|
||||
const parentCommentId = 5;
|
||||
const mockComment = CommentModel(
|
||||
data: [],
|
||||
links: Links(first: '', last: '', prev: null, next: null),
|
||||
meta: Meta(currentPage: 1, from: null, lastPage: 1, links: [], perPage: 10, to: null, total: 0),
|
||||
);
|
||||
|
||||
when(() => mockFeedRepository.sendBlogPostComment(id: id, commentText: commentText, parentCommentId: parentCommentId))
|
||||
.thenAnswer((_) async => {});
|
||||
when(() => mockFeedRepository.getBlogPostComments(id: id))
|
||||
.thenAnswer((_) async => mockComment);
|
||||
|
||||
await cubit.sendComment(
|
||||
id: id,
|
||||
commentText: commentText,
|
||||
commentSourceType: CommentSourceType.blogPost,
|
||||
parentCommentId: parentCommentId,
|
||||
);
|
||||
|
||||
verify(() => mockFeedRepository.sendBlogPostComment(id: id, commentText: commentText, parentCommentId: parentCommentId)).called(1);
|
||||
});
|
||||
|
||||
test('sendComment - обработка ошибки', () async {
|
||||
const id = '1';
|
||||
const commentText = 'Test comment';
|
||||
|
||||
when(() => mockFeedRepository.sendBlogPostComment(id: id, commentText: commentText, parentCommentId: null))
|
||||
.thenThrow(Exception('Error'));
|
||||
|
||||
await cubit.sendComment(
|
||||
id: id,
|
||||
commentText: commentText,
|
||||
commentSourceType: CommentSourceType.blogPost,
|
||||
);
|
||||
|
||||
expect(cubit.state, isA<CommentsStateError>());
|
||||
final errorState = cubit.state as CommentsStateError;
|
||||
expect(errorState.errorMessage, contains('Error'));
|
||||
});
|
||||
|
||||
test('deleteComment - возвращает false если state не loaded', () async {
|
||||
// Начальное состояние не loaded
|
||||
final result = await cubit.deleteComment(id: 1);
|
||||
expect(result, false);
|
||||
});
|
||||
|
||||
test('deleteComment - обработка ошибки при удалении', () async {
|
||||
final comment = Comment(
|
||||
id: 1,
|
||||
authorName: 'Test',
|
||||
authorSlug: 'test',
|
||||
authorProfileIcon: '',
|
||||
body: 'Test',
|
||||
childrenComments: [],
|
||||
createdAt: DateTime.now(),
|
||||
);
|
||||
final mockComment = CommentModel(
|
||||
data: [comment],
|
||||
links: const Links(first: '', last: '', prev: null, next: null),
|
||||
meta: const Meta(currentPage: 1, from: null, lastPage: 1, links: [], perPage: 10, to: null, total: 0),
|
||||
);
|
||||
|
||||
when(() => mockFeedRepository.getBlogPostComments(id: any(named: 'id')))
|
||||
.thenAnswer((_) async => mockComment);
|
||||
await cubit.getComments('1', CommentSourceType.blogPost);
|
||||
|
||||
when(() => mockCommentsRepository.deleteComment(id: 1))
|
||||
.thenThrow(Exception('Delete error'));
|
||||
|
||||
final result = await cubit.deleteComment(id: 1);
|
||||
|
||||
expect(result, false);
|
||||
// Состояние должно вернуться к исходному
|
||||
final state = cubit.state as CommentsStateLoaded;
|
||||
expect(state.comment.data.length, 1);
|
||||
});
|
||||
|
||||
test('updateComment - обработка ошибки при обновлении', () async {
|
||||
final comment = Comment(
|
||||
id: 1,
|
||||
authorName: 'Test',
|
||||
authorSlug: 'test',
|
||||
authorProfileIcon: '',
|
||||
body: 'Old text',
|
||||
childrenComments: [],
|
||||
createdAt: DateTime.now(),
|
||||
);
|
||||
final mockComment = CommentModel(
|
||||
data: [comment],
|
||||
links: const Links(first: '', last: '', prev: null, next: null),
|
||||
meta: const Meta(currentPage: 1, from: null, lastPage: 1, links: [], perPage: 10, to: null, total: 0),
|
||||
);
|
||||
|
||||
when(() => mockFeedRepository.getBlogPostComments(id: any(named: 'id')))
|
||||
.thenAnswer((_) async => mockComment);
|
||||
await cubit.getComments('1', CommentSourceType.blogPost);
|
||||
|
||||
when(() => mockCommentsRepository.updateComment(id: 1, body: 'New text'))
|
||||
.thenThrow(Exception('Update error'));
|
||||
|
||||
final result = await cubit.updateComment(id: 1, body: 'New text');
|
||||
|
||||
expect(result, false);
|
||||
// Состояние должно вернуться к исходному
|
||||
final state = cubit.state as CommentsStateLoaded;
|
||||
expect(state.comment.data.first.body, 'Old text');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -52,5 +52,45 @@ void main() {
|
||||
|
||||
expect(model1 == model2, false);
|
||||
});
|
||||
|
||||
test('fromJson - создает модель из JSON', () {
|
||||
final json = {'body': 'Test comment body'};
|
||||
final model = CommentUpdateModel.fromJson(json);
|
||||
|
||||
expect(model.body, 'Test comment body');
|
||||
});
|
||||
|
||||
test('fromJson - обрабатывает пустую строку', () {
|
||||
final json = {'body': ''};
|
||||
final model = CommentUpdateModel.fromJson(json);
|
||||
|
||||
expect(model.body, '');
|
||||
});
|
||||
|
||||
test('fromJson - обрабатывает длинный текст', () {
|
||||
final longBody = 'A' * 1000;
|
||||
final json = {'body': longBody};
|
||||
final model = CommentUpdateModel.fromJson(json);
|
||||
|
||||
expect(model.body, longBody);
|
||||
expect(model.body.length, 1000);
|
||||
});
|
||||
|
||||
test('toJson - преобразует модель в JSON', () {
|
||||
final model = CommentUpdateModel(body: 'Test comment body');
|
||||
final json = model.toJson();
|
||||
|
||||
expect(json, isA<Map<String, dynamic>>());
|
||||
expect(json['body'], 'Test comment body');
|
||||
});
|
||||
|
||||
test('toJson и fromJson - обратное преобразование', () {
|
||||
final originalModel = CommentUpdateModel(body: 'Test comment');
|
||||
final json = originalModel.toJson();
|
||||
final restoredModel = CommentUpdateModel.fromJson(json);
|
||||
|
||||
expect(restoredModel.body, originalModel.body);
|
||||
expect(restoredModel, originalModel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,14 +1,25 @@
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/core/comments/presentation/comments_actions_bottom_sheet.dart';
|
||||
import 'package:eatvio_app/core/widgets/bottom_sheet_action_widget.dart';
|
||||
import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
void main() {
|
||||
group('CommentsActionsBottomSheet', () {
|
||||
Widget createTestWidget(Widget child) {
|
||||
return MaterialApp(
|
||||
final router = GoRouter(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/',
|
||||
builder: (context, state) => Scaffold(body: child),
|
||||
),
|
||||
],
|
||||
);
|
||||
return MaterialApp.router(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
@@ -17,9 +28,7 @@ void main() {
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
home: Scaffold(
|
||||
body: child,
|
||||
),
|
||||
routerConfig: router,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,15 +53,7 @@ void main() {
|
||||
testWidgets('displays edit option for my comment', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
createTestWidget(
|
||||
CommentsActionsBottomSheet(
|
||||
isMyComment: true,
|
||||
reply: null,
|
||||
copy: () {},
|
||||
edit: (text) {},
|
||||
delete: () {},
|
||||
complain: () {},
|
||||
commentText: 'Test comment',
|
||||
),
|
||||
CommentsActionsBottomSheet(isMyComment: true, reply: null, copy: () {}, edit: (text) {}, delete: () {}, complain: () {}, commentText: 'Test comment'),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -80,19 +81,523 @@ void main() {
|
||||
testWidgets('shows edit mode when edit is tapped', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
createTestWidget(
|
||||
CommentsActionsBottomSheet(
|
||||
isMyComment: true,
|
||||
reply: null,
|
||||
copy: () {},
|
||||
edit: (text) {},
|
||||
delete: () {},
|
||||
complain: () {},
|
||||
commentText: 'Test comment',
|
||||
),
|
||||
CommentsActionsBottomSheet(isMyComment: true, reply: null, copy: () {}, edit: (text) {}, delete: () {}, complain: () {}, commentText: 'Test comment'),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byType(CommentsActionsBottomSheet), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('initializes with comment text in controller', (tester) async {
|
||||
const commentText = 'Initial comment text';
|
||||
await tester.pumpWidget(
|
||||
createTestWidget(
|
||||
CommentsActionsBottomSheet(isMyComment: true, reply: null, copy: () {}, edit: (text) {}, delete: () {}, complain: () {}, commentText: commentText),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byType(CommentsActionsBottomSheet), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('calls copy callback when copy is tapped', (tester) async {
|
||||
bool copyCalled = false;
|
||||
final router = GoRouter(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/',
|
||||
builder: (context, state) => Scaffold(
|
||||
body: Builder(
|
||||
builder: (context) => ElevatedButton(
|
||||
onPressed: () {
|
||||
showCommentsActionsBottomSheet(
|
||||
context,
|
||||
reply: () {},
|
||||
copy: () {
|
||||
copyCalled = true;
|
||||
},
|
||||
edit: (text) {},
|
||||
delete: () {},
|
||||
complain: () {},
|
||||
commentText: 'Test comment',
|
||||
isMyComment: false,
|
||||
);
|
||||
},
|
||||
child: const Text('Show'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp.router(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
routerConfig: router,
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('Show'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Находим кнопку копирования (вторая кнопка для not my comment)
|
||||
final actionWidgets = find.byType(BottomSheetActionWidget);
|
||||
expect(actionWidgets, findsWidgets);
|
||||
await tester.tap(actionWidgets.at(1)); // copy button
|
||||
await tester.pump();
|
||||
|
||||
expect(copyCalled, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('calls delete callback when delete is tapped for my comment', (tester) async {
|
||||
bool deleteCalled = false;
|
||||
final router = GoRouter(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/',
|
||||
builder: (context, state) => Scaffold(
|
||||
body: Builder(
|
||||
builder: (context) => ElevatedButton(
|
||||
onPressed: () {
|
||||
showCommentsActionsBottomSheet(
|
||||
context,
|
||||
reply: null,
|
||||
copy: () {},
|
||||
edit: (text) {},
|
||||
delete: () {
|
||||
deleteCalled = true;
|
||||
},
|
||||
complain: () {},
|
||||
commentText: 'Test comment',
|
||||
isMyComment: true,
|
||||
);
|
||||
},
|
||||
child: const Text('Show'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp.router(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
routerConfig: router,
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('Show'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Находим кнопку удаления (последняя кнопка для my comment)
|
||||
final actionWidgets = find.byType(BottomSheetActionWidget);
|
||||
expect(actionWidgets, findsWidgets);
|
||||
await tester.tap(actionWidgets.last); // delete button
|
||||
await tester.pump();
|
||||
|
||||
expect(deleteCalled, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('calls complain callback when complain is tapped for not my comment', (tester) async {
|
||||
bool complainCalled = false;
|
||||
final router = GoRouter(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/',
|
||||
builder: (context, state) => Scaffold(
|
||||
body: Builder(
|
||||
builder: (context) => ElevatedButton(
|
||||
onPressed: () {
|
||||
showCommentsActionsBottomSheet(
|
||||
context,
|
||||
reply: () {},
|
||||
copy: () {},
|
||||
edit: (text) {},
|
||||
delete: () {},
|
||||
complain: () {
|
||||
complainCalled = true;
|
||||
},
|
||||
commentText: 'Test comment',
|
||||
isMyComment: false,
|
||||
);
|
||||
},
|
||||
child: const Text('Show'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp.router(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
routerConfig: router,
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('Show'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Находим кнопку жалобы (последняя кнопка для not my comment)
|
||||
final actionWidgets = find.byType(BottomSheetActionWidget);
|
||||
expect(actionWidgets, findsWidgets);
|
||||
await tester.tap(actionWidgets.last); // complain button
|
||||
await tester.pump();
|
||||
|
||||
expect(complainCalled, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('shows edit text field when edit button is tapped', (tester) async {
|
||||
final router = GoRouter(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/',
|
||||
builder: (context, state) => Scaffold(
|
||||
body: Builder(
|
||||
builder: (context) => ElevatedButton(
|
||||
onPressed: () {
|
||||
showCommentsActionsBottomSheet(
|
||||
context,
|
||||
reply: null,
|
||||
copy: () {},
|
||||
edit: (text) {},
|
||||
delete: () {},
|
||||
complain: () {},
|
||||
commentText: 'Test comment',
|
||||
isMyComment: true,
|
||||
);
|
||||
},
|
||||
child: const Text('Show'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp.router(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
routerConfig: router,
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('Show'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(CommentsActionsBottomSheet), findsOneWidget);
|
||||
|
||||
// Нажимаем на кнопку редактирования
|
||||
final editButtons = find.byType(BottomSheetActionWidget);
|
||||
expect(editButtons, findsWidgets);
|
||||
await tester.tap(editButtons.first);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// После нажатия на кнопку редактирования должен появиться текстовое поле
|
||||
expect(find.byType(CustomTextFormField), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('showCommentsActionsBottomSheet - отображает bottom sheet', (tester) async {
|
||||
final router = GoRouter(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/',
|
||||
builder: (context, state) => Scaffold(
|
||||
body: Center(
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
showCommentsActionsBottomSheet(
|
||||
context,
|
||||
reply: () {},
|
||||
copy: () {},
|
||||
edit: (text) {},
|
||||
delete: () {},
|
||||
complain: () {},
|
||||
commentText: 'Test comment',
|
||||
isMyComment: false,
|
||||
);
|
||||
},
|
||||
child: const Text('Show Bottom Sheet'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp.router(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
routerConfig: router,
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('Show Bottom Sheet'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(CommentsActionsBottomSheet), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('edit mode - показывает текстовое поле и кнопку отправки', (tester) async {
|
||||
String? editedText;
|
||||
final router = GoRouter(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/',
|
||||
builder: (context, state) => Scaffold(
|
||||
body: Builder(
|
||||
builder: (context) => ElevatedButton(
|
||||
onPressed: () {
|
||||
showCommentsActionsBottomSheet(
|
||||
context,
|
||||
reply: null,
|
||||
copy: () {},
|
||||
edit: (text) {
|
||||
editedText = text;
|
||||
},
|
||||
delete: () {},
|
||||
complain: () {},
|
||||
commentText: 'Original comment',
|
||||
isMyComment: true,
|
||||
);
|
||||
},
|
||||
child: const Text('Show'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp.router(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
routerConfig: router,
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('Show'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Находим и нажимаем на кнопку редактирования (первая кнопка для my comment)
|
||||
final editButtons = find.byType(BottomSheetActionWidget);
|
||||
expect(editButtons, findsWidgets);
|
||||
await tester.tap(editButtons.first);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Проверяем, что появилось текстовое поле
|
||||
expect(find.byType(CustomTextFormField), findsOneWidget);
|
||||
|
||||
// Вводим новый текст
|
||||
await tester.enterText(find.byType(CustomTextFormField), 'Edited comment');
|
||||
await tester.pump();
|
||||
|
||||
// Нажимаем на кнопку отправки (текст достаточно длинный > 2 символов)
|
||||
final sendButton = find.byIcon(Icons.send_rounded);
|
||||
expect(sendButton, findsOneWidget);
|
||||
// Используем pump() вместо pumpAndSettle() чтобы избежать ошибок с GoRouter.pop()
|
||||
await tester.tap(sendButton);
|
||||
await tester.pump();
|
||||
|
||||
expect(editedText, 'Edited comment');
|
||||
});
|
||||
|
||||
testWidgets('edit mode - кнопка отправки неактивна при коротком тексте', (tester) async {
|
||||
final router = GoRouter(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/',
|
||||
builder: (context, state) => Scaffold(
|
||||
body: Builder(
|
||||
builder: (context) => ElevatedButton(
|
||||
onPressed: () {
|
||||
showCommentsActionsBottomSheet(
|
||||
context,
|
||||
reply: null,
|
||||
copy: () {},
|
||||
edit: (text) {},
|
||||
delete: () {},
|
||||
complain: () {},
|
||||
commentText: 'Original',
|
||||
isMyComment: true,
|
||||
);
|
||||
},
|
||||
child: const Text('Show'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp.router(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
routerConfig: router,
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('Show'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Находим и нажимаем на кнопку редактирования
|
||||
final editButtons = find.byType(BottomSheetActionWidget);
|
||||
expect(editButtons, findsWidgets);
|
||||
await tester.tap(editButtons.first);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Вводим короткий текст (меньше 3 символов)
|
||||
await tester.enterText(find.byType(CustomTextFormField), 'Hi');
|
||||
await tester.pump();
|
||||
|
||||
// Кнопка отправки должна быть неактивной (серая)
|
||||
expect(find.byType(CustomTextFormField), findsOneWidget);
|
||||
expect(find.byIcon(Icons.send_rounded), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('displays delete option for my comment', (tester) async {
|
||||
final router = GoRouter(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/',
|
||||
builder: (context, state) => Scaffold(
|
||||
body: Builder(
|
||||
builder: (context) => ElevatedButton(
|
||||
onPressed: () {
|
||||
showCommentsActionsBottomSheet(
|
||||
context,
|
||||
reply: () {},
|
||||
copy: () {},
|
||||
edit: (text) {},
|
||||
delete: () {},
|
||||
complain: () {},
|
||||
commentText: 'Test comment',
|
||||
isMyComment: true,
|
||||
);
|
||||
},
|
||||
child: const Text('Show'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp.router(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
routerConfig: router,
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('Show'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(CommentsActionsBottomSheet), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('displays complain option for not my comment', (tester) async {
|
||||
final router = GoRouter(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/',
|
||||
builder: (context, state) => Scaffold(
|
||||
body: Builder(
|
||||
builder: (context) => ElevatedButton(
|
||||
onPressed: () {
|
||||
showCommentsActionsBottomSheet(
|
||||
context,
|
||||
reply: null,
|
||||
copy: () {},
|
||||
edit: (text) {},
|
||||
delete: () {},
|
||||
complain: () {},
|
||||
commentText: 'Test comment',
|
||||
isMyComment: false,
|
||||
);
|
||||
},
|
||||
child: const Text('Show'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp.router(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
routerConfig: router,
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('Show'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(CommentsActionsBottomSheet), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user