feat(personalized_feed): added fixtures for new feed, added new feed parsing and layout, added webview player for post videos

This commit is contained in:
misha
2026-07-20 16:47:19 +03:00
parent bd2de07b8f
commit 48a984f5e9
23 changed files with 1330 additions and 903 deletions

View File

@@ -0,0 +1,56 @@
import 'package:eatvio_app/core/app_config.dart';
import 'package:eatvio_app/core/app_initializer.dart';
import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/features/feed/models/post_feed_mapper.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_test/flutter_test.dart';
import '../../../fixtures/feed_fixtures.dart';
void main() {
group('PostFeedMapper', () {
setUpAll(() async {
await sl.reset();
dotenv.loadFromString(envString: 'DEV_BASE_URL=http://localhost\nBASE_URL=http://localhost');
sl.registerLazySingleton<AppConfig>(() => AppConfig(buildType: AppBuildType.tests)..setBaseUrl('http://localhost'));
});
test('maps fixture item post_id to FeedBlogPostModel.id', () {
final item = FeedFixtures.postFeedItem();
final model = PostFeedMapper.fromPostFeedItem(item, currentUserId: 10);
expect(model.id, 1);
expect(model.author.authorIsMe, isTrue);
expect(model.author.authorSlug, 'anna-ivanova');
expect(model.images, hasLength(2));
expect(model.videoUrl, isEmpty);
expect(model.videoEmbedUrl, isNull);
expect(model.title, 'Завтрак с овсянкой');
expect(model.image, 'http://localhost/storage/posts/oatmeal.jpg');
expect(model.author.isEntitySubscribedByMe, isFalse);
});
test('maps fixture embed video post and likes', () {
final item = FeedFixtures.postFeedItem(index: 1);
final model = PostFeedMapper.fromPostFeedItem(item);
expect(model.id, 2);
expect(model.videoUrl, isEmpty);
expect(model.videoEmbedUrl, 'https://www.youtube.com/embed/dQw4w9WgXcQ');
expect(model.wasLikedByMe, isTrue);
expect(model.totalLikes, 42);
expect(model.author.authorIsMe, isFalse);
expect(model.author.isEntitySubscribedByMe, isTrue);
});
test('maps all fixture posts', () {
final posts = FeedFixtures.mappedFeedPosts(currentUserId: 11);
expect(posts, hasLength(3));
expect(posts[1].author.authorIsMe, isTrue);
expect(posts[1].author.isEntitySubscribedByMe, isTrue);
expect(posts[2].videoEmbedUrl, contains('rutube.ru/play/embed'));
expect(posts[2].author.isEntitySubscribedByMe, isNull);
});
});
}

View File

@@ -0,0 +1,57 @@
import 'package:flutter_test/flutter_test.dart';
import '../../../fixtures/feed_fixtures.dart';
void main() {
group('PostFeedPaginationModel fixtures', () {
test('parses first page with gallery, video and next_cursor', () {
final model = FeedFixtures.postFeedPaginationModel();
expect(model.data, hasLength(3));
expect(model.meta.perPage, 20);
expect(model.meta.nextCursor, 'eyJpZCI6MTAzfQ');
expect(model.meta.prevCursor, isNull);
expect(model.links.next, contains('cursor=eyJpZCI6MTAzfQ'));
final withGallery = model.data[0];
expect(withGallery.postId, 1);
expect(withGallery.images, hasLength(2));
expect(withGallery.images.first.orientation, 'horizontal');
expect(withGallery.videoEmbedUrl, isNull);
expect(withGallery.isEntitySubscribedByMe, isFalse);
expect(withGallery.postAuthorDetails?.slug, 'anna-ivanova');
expect(withGallery.postAuthorDetails?.isConsultant, isTrue);
final withYoutubeEmbed = model.data[1];
expect(withYoutubeEmbed.postId, 2);
expect(withYoutubeEmbed.videoEmbedUrl, 'https://www.youtube.com/embed/dQw4w9WgXcQ');
expect(withYoutubeEmbed.postIsLikedByUser, isTrue);
expect(withYoutubeEmbed.isEntitySubscribedByMe, isTrue);
expect(withYoutubeEmbed.images, isEmpty);
final withRutubeEmbed = model.data[2];
expect(withRutubeEmbed.postId, 3);
expect(withRutubeEmbed.postImageUrl, isNull);
expect(withRutubeEmbed.images, hasLength(1));
expect(withRutubeEmbed.videoEmbedUrl, contains('rutube.ru/play/embed'));
expect(withRutubeEmbed.isEntitySubscribedByMe, isNull); });
test('parses next page without next_cursor', () {
final model = FeedFixtures.postFeedNextPagePaginationModel();
expect(model.data, hasLength(1));
expect(model.data.first.postId, 4);
expect(model.meta.nextCursor, isNull);
expect(model.meta.prevCursor, 'eyJpZCI6MTAzfQ');
expect(model.links.next, isNull);
});
test('parses empty feed', () {
final model = FeedFixtures.postFeedEmptyPaginationModel();
expect(model.data, isEmpty);
expect(model.meta.nextCursor, isNull);
expect(model.links.next, isNull);
});
});
}