feat(tests): updated tests coverage to 66.5%

This commit is contained in:
misha
2026-01-14 18:47:11 +03:00
parent 497ff19cfa
commit 13ccf56df0
102 changed files with 10146 additions and 379 deletions

View File

@@ -189,5 +189,100 @@ void main() {
expect(comment.authorName, 'John Doe');
expect(comment.body, 'Test comment');
});
test('toJson serializes Comment correctly', () {
final comment = Comment(
id: 1,
authorName: 'John Doe',
authorSlug: 'john-doe',
authorProfileIcon: 'icon.jpg',
body: 'Test comment body',
childrenComments: [],
createdAt: DateTime(2023, 1, 1),
);
final json = comment.toJson();
expect(json['id'], 1);
expect(json['author_name'], 'John Doe');
expect(json['author_slug'], 'john-doe');
expect(json['body'], 'Test comment body');
expect(json['children_comments'], isA<List>());
});
test('toJson serializes Comment with nested children correctly', () {
final childComment = Comment(
id: 2,
authorName: 'Jane Smith',
authorSlug: 'jane-smith',
authorProfileIcon: 'icon2.jpg',
body: 'Reply comment',
childrenComments: [],
createdAt: DateTime(2023, 1, 2),
);
final parentComment = Comment(
id: 1,
authorName: 'John Doe',
authorSlug: 'john-doe',
authorProfileIcon: 'icon1.jpg',
body: 'Parent comment',
childrenComments: [childComment],
createdAt: DateTime(2023, 1, 1),
);
final json = parentComment.toJson();
expect(json['id'], 1);
expect(json['children_comments'], isA<List>());
expect((json['children_comments'] as List).length, 1);
});
});
group('CommentModel', () {
test('toJson serializes CommentModel correctly', () {
final comments = [
Comment(
id: 1,
authorName: 'John Doe',
authorSlug: 'john-doe',
authorProfileIcon: 'icon1.jpg',
body: 'First comment',
childrenComments: [],
createdAt: DateTime(2023, 1, 1),
),
];
const links = Links(
first: 'http://example.com?page=1',
last: 'http://example.com?page=1',
prev: null,
next: null,
);
const meta = Meta(
currentPage: 1,
from: 1,
lastPage: 1,
links: [],
path: '/api/comments',
perPage: 10,
to: 1,
total: 1,
);
final model = CommentModel(
data: comments,
links: links,
meta: meta,
);
final json = model.toJson();
expect(json.containsKey('data'), isTrue);
expect(json.containsKey('links'), isTrue);
expect(json.containsKey('meta'), isTrue);
expect((json['data'] as List).length, 1);
});
});
}

View File

@@ -0,0 +1,255 @@
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('Portion enum', () {
test('has all expected values', () {
expect(Portion.values.length, 3);
expect(Portion.grams, isNotNull);
expect(Portion.milliliters, isNotNull);
expect(Portion.pcs, isNotNull);
});
test('getPortionFromValue returns correct enum for valid values', () {
expect(Portion.getPortionFromValue('gr'), Portion.grams);
expect(Portion.getPortionFromValue('milliliters'), Portion.milliliters);
expect(Portion.getPortionFromValue('pcs'), Portion.pcs);
});
test('getPortionFromValue returns null for invalid values', () {
expect(Portion.getPortionFromValue('invalid'), isNull);
expect(Portion.getPortionFromValue(''), isNull);
});
test('getValue returns correct string values', () {
expect(Portion.grams.getValue(), 'gr');
expect(Portion.milliliters.getValue(), 'milliliters');
expect(Portion.pcs.getValue(), 'pcs');
});
});
group('DietType', () {
test('hasAtLeastOneType returns true when at least one type is true', () {
const dietType = DietType(light: true, veg: false, carb: false, meat: false);
expect(dietType.hasAtLeastOneType(), isTrue);
});
test('hasAtLeastOneType returns true when veg is true', () {
const dietType = DietType(light: null, veg: true, carb: null, meat: null);
expect(dietType.hasAtLeastOneType(), isTrue);
});
test('hasAtLeastOneType returns true when carb is true', () {
const dietType = DietType(light: null, veg: null, carb: true, meat: null);
expect(dietType.hasAtLeastOneType(), isTrue);
});
test('hasAtLeastOneType returns true when meat is true', () {
const dietType = DietType(light: null, veg: null, carb: null, meat: true);
expect(dietType.hasAtLeastOneType(), isTrue);
});
test('hasAtLeastOneType returns false when all types are false', () {
const dietType = DietType(light: false, veg: false, carb: false, meat: false);
expect(dietType.hasAtLeastOneType(), isFalse);
});
test('hasAtLeastOneType returns false when all types are null', () {
const dietType = DietType(light: null, veg: null, carb: null, meat: null);
expect(dietType.hasAtLeastOneType(), isFalse);
});
test('fromJson parses all fields correctly', () {
final json = {
'light': true,
'veg': false,
'carb': true,
'meat': false,
};
final model = DietType.fromJson(json);
expect(model.light, isTrue);
expect(model.veg, isFalse);
expect(model.carb, isTrue);
expect(model.meat, isFalse);
});
test('toJson serializes all fields correctly', () {
const model = DietType(light: true, veg: false, carb: true, meat: false);
final json = model.toJson();
expect(json['light'], isTrue);
expect(json['veg'], isFalse);
expect(json['carb'], isTrue);
expect(json['meat'], isFalse);
});
});
group('CreatedDiet', () {
test('fromJson parses id correctly', () {
final json = {'id': 123};
final model = CreatedDiet.fromJson(json);
expect(model.id, 123);
});
test('toJson serializes id correctly', () {
const model = CreatedDiet(id: 123);
final json = model.toJson();
expect(json['id'], 123);
});
});
group('DailyNutrition', () {
test('fromJson parses all fields correctly', () {
final json = {
'energy': 2000.0,
'proteins': 100.0,
'fats': 50.0,
'carbohydrates': 250.0,
};
final model = DailyNutrition.fromJson(json);
expect(model.energy, 2000.0);
expect(model.proteins, 100.0);
expect(model.fats, 50.0);
expect(model.carbohydrates, 250.0);
});
test('toJson serializes all fields correctly', () {
const model = DailyNutrition(
energy: 2000.0,
proteins: 100.0,
fats: 50.0,
carbohydrates: 250.0,
);
final json = model.toJson();
expect(json['energy'], 2000.0);
expect(json['proteins'], 100.0);
expect(json['fats'], 50.0);
expect(json['carbohydrates'], 250.0);
});
});
group('DailySchedule', () {
test('fromJson parses all fields correctly', () {
final json = {
'name': 'Breakfast',
'portion': 'gr',
'quantity': '100',
'nutrition': {
'energy': 200.0,
'proteins': 10.0,
'fats': 5.0,
'carbohydrates': 25.0,
},
};
final model = DailySchedule.fromJson(json);
expect(model.name, 'Breakfast');
expect(model.portion, Portion.grams);
expect(model.quantity, 100);
expect(model.dailyNutrition, isNotNull);
expect(model.dailyNutrition?.energy, 200.0);
});
test('fromJson parses quantity as int', () {
final json = {
'name': 'Lunch',
'portion': 'milliliters',
'quantity': 200,
};
final model = DailySchedule.fromJson(json);
expect(model.quantity, 200);
});
test('toJson serializes all fields correctly', () {
const nutrition = DailyNutrition(
energy: 200.0,
proteins: 10.0,
fats: 5.0,
carbohydrates: 25.0,
);
const model = DailySchedule(
name: 'Breakfast',
portion: Portion.grams,
quantity: 100,
dailyNutrition: nutrition,
);
final json = model.toJson();
expect(json['name'], 'Breakfast');
expect(json['portion'], 'gr');
expect(json['quantity'], 100);
});
});
group('Author', () {
test('fromJson parses all fields correctly', () {
final json = {
'author_slug': 'author-1',
'author_name': 'Author Name',
'author_profile_icon': 'icon.jpg',
'author_is_me': true,
'is_entity_subscribed_by_me': false,
'author_place_in_rating': 5,
};
final model = Author.fromJson(json);
expect(model.authorSlug, 'author-1');
expect(model.authorName, 'Author Name');
expect(model.authorProfileIcon, 'icon.jpg');
expect(model.authorIsMe, isTrue);
expect(model.isEntitySubscribedByMe, isFalse);
expect(model.authorPlaceInRating, 5);
});
test('fromJson handles null optional fields', () {
final json = {
'author_slug': 'author-1',
'author_name': 'Author Name',
'author_profile_icon': 'icon.jpg',
'author_is_me': false,
};
final model = Author.fromJson(json);
expect(model.isEntitySubscribedByMe, isNull);
expect(model.authorPlaceInRating, isNull);
});
test('toJson serializes all fields correctly', () {
const model = Author(
authorSlug: 'author-1',
authorName: 'Author Name',
authorProfileIcon: 'icon.jpg',
authorIsMe: true,
isEntitySubscribedByMe: false,
authorPlaceInRating: 5,
);
final json = model.toJson();
expect(json['author_slug'], 'author-1');
expect(json['author_name'], 'Author Name');
expect(json['author_profile_icon'], 'icon.jpg');
expect(json['author_is_me'], isTrue);
expect(json['is_entity_subscribed_by_me'], isFalse);
expect(json['author_place_in_rating'], 5);
});
});
}

View File

@@ -134,5 +134,44 @@ void main() {
expect(model.state, state);
}
});
test('toJson serializes FeedBlogPostModel correctly', () {
const author = Author(
authorSlug: 'author1',
authorName: 'Author Name',
authorProfileIcon: 'icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: false,
authorPlaceInRating: null,
);
final model = FeedBlogPostModel(
id: 1,
state: 'published',
image: 'post.jpg',
description: 'Blog post description',
author: author,
videoUrl: 'https://example.com/video.mp4',
createdAt: DateTime(2023, 1, 1),
updatedAt: DateTime(2023, 1, 2),
title: 'Blog Post Title',
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: false,
);
final json = model.toJson();
expect(json['id'], 1);
expect(json['title'], 'Blog Post Title');
expect(json['state'], 'published');
expect(json['description'], 'Blog post description');
expect(json['total_likes'], 10);
expect(json['total_views'], 100);
expect(json['total_comments'], 5);
expect(json['was_liked_by_me'], false);
expect(json.containsKey('author'), isTrue);
});
});
}

View File

@@ -1,73 +1,96 @@
import 'package:eatvio_app/features/feed/models/feed_blog_post_settings_model.dart';
import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/core/models/pagination_model.dart';
import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
import 'package:eatvio_app/features/feed/models/feed_blog_post_settings_model.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('FeedBlogPostSettingsModel', () {
test('creates FeedBlogPostSettingsModel with empty list', () {
const meta = Meta(
currentPage: 1,
from: 1,
lastPage: 1,
links: [],
path: '/api/posts',
perPage: 10,
to: 0,
total: 0,
test('creates FeedBlogPostSettingsModel with blog posts', () {
const author = Author(
authorSlug: 'author1',
authorName: 'Author Name',
authorProfileIcon: 'icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: false,
authorPlaceInRating: null,
);
const model = FeedBlogPostSettingsModel(
feedBlogPostList: [],
meta: meta,
);
final blogPosts = [
FeedBlogPostModel(
id: 1,
state: 'published',
image: 'post1.jpg',
description: 'Description 1',
author: author,
videoUrl: '',
createdAt: DateTime(2023, 1, 1),
updatedAt: DateTime(2023, 1, 2),
title: 'Post 1',
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: false,
),
FeedBlogPostModel(
id: 2,
state: 'published',
image: 'post2.jpg',
description: 'Description 2',
author: author,
videoUrl: '',
createdAt: DateTime(2023, 1, 3),
updatedAt: DateTime(2023, 1, 4),
title: 'Post 2',
totalLikes: 20,
totalViews: 200,
totalComments: 10,
wasLikedByMe: true,
),
];
const meta = Meta(currentPage: 1, from: 1, lastPage: 1, links: [], path: '/api/blog-posts', perPage: 10, to: 2, total: 2);
final model = FeedBlogPostSettingsModel(feedBlogPostList: blogPosts, meta: meta);
expect(model.feedBlogPostList.length, 2);
expect(model.feedBlogPostList[0].id, 1);
expect(model.feedBlogPostList[1].id, 2);
expect(model.meta.total, 2);
});
test('creates FeedBlogPostSettingsModel with empty list', () {
const meta = Meta(currentPage: 1, from: null, lastPage: 1, links: [], path: '/api/blog-posts', perPage: 10, to: null, total: 0);
const model = FeedBlogPostSettingsModel(feedBlogPostList: [], meta: meta);
expect(model.feedBlogPostList, isEmpty);
expect(model.meta.total, 0);
});
test('creates FeedBlogPostSettingsModel with blog posts', () {
final blogPosts = [
FeedBlogPostModel(
id: 1,
title: 'Test Post',
image: 'image.jpg',
description: 'Test description',
state: 'published',
videoUrl: '',
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: false,
author: const Author(
authorSlug: 'author1',
authorName: 'Author',
authorProfileIcon: 'photo.jpg',
authorIsMe: false,
isEntitySubscribedByMe: false,
authorPlaceInRating: null,
),
),
];
test('fromJson creates FeedBlogPostSettingsModel from JSON', () {
final json = {
'data': [
{
'id': 1,
'state': 'published',
'image': 'post.jpg',
'description': 'Test description',
'author': {'author_slug': 'author1', 'author_name': 'Author', 'author_profile_icon': 'icon.jpg', 'author_is_me': false},
'video_url': '',
'created_at': '2023-01-01T00:00:00Z',
'updated_at': '2023-01-02T00:00:00Z',
'title': 'Test Post',
'total_likes': 10,
'total_views': 100,
'total_comments': 5,
'was_liked_by_me': false,
},
],
'meta': {'current_page': 1, 'from': 1, 'last_page': 1, 'links': [], 'path': '/api/blog-posts', 'per_page': 10, 'to': 1, 'total': 1},
};
const meta = Meta(
currentPage: 1,
from: 1,
lastPage: 1,
links: [],
path: '/api/posts',
perPage: 10,
to: 1,
total: 1,
);
final model = FeedBlogPostSettingsModel(
feedBlogPostList: blogPosts,
meta: meta,
);
final model = FeedBlogPostSettingsModel.fromJson(json);
expect(model.feedBlogPostList.length, 1);
expect(model.feedBlogPostList[0].id, 1);
@@ -75,47 +98,43 @@ void main() {
expect(model.meta.total, 1);
});
test('creates FeedBlogPostSettingsModel from JSON', () {
final json = {
'data': [
{
'id': 1,
'title': 'Test Post',
'image': 'image.jpg',
'description': 'Test description',
'state': 'published',
'video_url': '',
'created_at': '2023-01-01T00:00:00Z',
'updated_at': '2023-01-01T00:00:00Z',
'total_comments': 5,
'was_liked_by_me': false,
'total_likes': 10,
'total_views': 100,
'author': {
'author_slug': 'author1',
'author_name': 'Author',
'author_profile_icon': 'photo.jpg',
'author_is_me': false,
},
},
],
'meta': {
'current_page': 1,
'from': 1,
'last_page': 1,
'links': [],
'path': '/api/posts',
'per_page': 10,
'to': 1,
'total': 1,
},
};
test('toJson serializes FeedBlogPostSettingsModel correctly', () {
const author = Author(
authorSlug: 'author1',
authorName: 'Author Name',
authorProfileIcon: 'icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: false,
authorPlaceInRating: null,
);
final model = FeedBlogPostSettingsModel.fromJson(json);
final blogPosts = [
FeedBlogPostModel(
id: 1,
state: 'published',
image: 'post1.jpg',
description: 'Description 1',
author: author,
videoUrl: '',
createdAt: DateTime(2023, 1, 1),
updatedAt: DateTime(2023, 1, 2),
title: 'Post 1',
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: false,
),
];
expect(model.feedBlogPostList.length, 1);
expect(model.feedBlogPostList[0].id, 1);
expect(model.meta.total, 1);
const meta = Meta(currentPage: 1, from: 1, lastPage: 1, links: [], path: '/api/blog-posts', perPage: 10, to: 1, total: 1);
final model = FeedBlogPostSettingsModel(feedBlogPostList: blogPosts, meta: meta);
final json = model.toJson();
expect(json.containsKey('data'), isTrue);
expect(json.containsKey('meta'), isTrue);
expect((json['data'] as List).length, 1);
});
});
}

View File

@@ -54,6 +54,35 @@ void main() {
expect(model.slug, 'consultant-1');
expect(model.totalScores, 450);
});
test('toJson serializes FeedConsultantModel correctly', () {
const model = FeedConsultantModel(
slug: 'consultant-1',
name: 'Consultant Name',
description: 'Test description',
ratingPlace: 1,
totalScores: 450,
photo: 'https://example.com/photo.jpg',
badges: [
BadgeModel(
id: 1,
title: 'Badge 1',
description: 'Description',
image: 'https://example.com/badge1.jpg',
type: 'type',
),
],
);
final json = model.toJson();
expect(json['slug'], 'consultant-1');
expect(json['name'], 'Consultant Name');
expect(json['additional_info'], 'Test description');
expect(json['rating_place'], 1);
expect(json['total_scores'], 450);
expect(json.containsKey('badges'), isTrue);
});
});
group('FeedConsultantPaginationModel', () {

View File

@@ -0,0 +1,356 @@
import 'package:eatvio_app/core/models/pagination_model.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('PlanType', () {
test('hasAtLeastOneType returns true when fit is true', () {
const planType = PlanType(fit: true, slim: null, behavior: null, wellness: null);
expect(planType.hasAtLeastOneType(), isTrue);
});
test('hasAtLeastOneType returns true when slim is true', () {
const planType = PlanType(fit: null, slim: true, behavior: null, wellness: null);
expect(planType.hasAtLeastOneType(), isTrue);
});
test('hasAtLeastOneType returns true when behavior is true', () {
const planType = PlanType(fit: null, slim: null, behavior: true, wellness: null);
expect(planType.hasAtLeastOneType(), isTrue);
});
test('hasAtLeastOneType returns true when wellness is true', () {
const planType = PlanType(fit: null, slim: null, behavior: null, wellness: true);
expect(planType.hasAtLeastOneType(), isTrue);
});
test('hasAtLeastOneType returns false when all types are false', () {
const planType = PlanType(fit: false, slim: false, behavior: false, wellness: false);
expect(planType.hasAtLeastOneType(), isFalse);
});
test('hasAtLeastOneType returns false when all types are null', () {
const planType = PlanType(fit: null, slim: null, behavior: null, wellness: null);
expect(planType.hasAtLeastOneType(), isFalse);
});
test('fromJson parses all fields correctly', () {
final json = {'fit': true, 'slim': false, 'behavior': true, 'wellness': false};
final model = PlanType.fromJson(json);
expect(model.fit, isTrue);
expect(model.slim, isFalse);
expect(model.behavior, isTrue);
expect(model.wellness, isFalse);
});
test('toJson serializes all fields correctly', () {
const model = PlanType(fit: true, slim: false, behavior: true, wellness: false);
final json = model.toJson();
expect(json['fit'], isTrue);
expect(json['slim'], isFalse);
expect(json['behavior'], isTrue);
expect(json['wellness'], isFalse);
});
});
group('PacketOptions', () {
test('empty factory creates instance with default values', () {
final options = PacketOptions.empty();
expect(options.items, isEmpty);
expect(options.price, 1200.0);
expect(options.short, '');
expect(options.description, '');
expect(options.hasPersonalDiet, isFalse);
});
test('fromJson parses all fields correctly', () {
final json = {
'items': ['item1', 'item2'],
'price': 1500,
'short': 'Short description',
'description_md': 'Full description',
'has_personal_diet': true,
};
final model = PacketOptions.fromJson(json);
expect(model.items, ['item1', 'item2']);
expect(model.price, 1500);
expect(model.short, 'Short description');
expect(model.description, 'Full description');
expect(model.hasPersonalDiet, isTrue);
});
test('fromJson parses items from Map', () {
final json = {
'items': {'key1': 'item1', 'key2': 'item2'},
'price': 1000,
'short': 'Short',
'description_md': 'Description',
'has_personal_diet': false,
};
final model = PacketOptions.fromJson(json);
expect(model.items.length, 2);
expect(model.items, contains('item1'));
expect(model.items, contains('item2'));
});
test('fromJson parses has_personal_diet as string "1"', () {
final json = {'items': [], 'price': 1000, 'short': 'Short', 'description_md': 'Description', 'has_personal_diet': '1'};
final model = PacketOptions.fromJson(json);
expect(model.hasPersonalDiet, isTrue);
});
test('fromJson parses has_personal_diet as string "0"', () {
final json = {'items': [], 'price': 1000, 'short': 'Short', 'description_md': 'Description', 'has_personal_diet': '0'};
final model = PacketOptions.fromJson(json);
expect(model.hasPersonalDiet, isFalse);
});
test('toJson serializes all fields correctly', () {
const model = PacketOptions(items: ['item1', 'item2'], price: 1500, short: 'Short', description: 'Description', hasPersonalDiet: true);
final json = model.toJson();
expect(json['items'], ['item1', 'item2']);
expect(json['price'], 1500);
expect(json['short'], 'Short');
expect(json['description_md'], 'Description');
expect(json['has_personal_diet'], isTrue);
});
});
group('PlanModel', () {
test('fromJson parses all fields correctly', () {
final json = {
'id': 1,
'slug': 'test-plan',
'name': 'Test Plan',
'image': 'https://example.com/image.jpg',
'duration': 30,
'state': 'active',
'type': {'fit': true, 'slim': false, 'behavior': false, 'wellness': false},
'description_md': 'Test description',
'packets_count': 3,
'packet1_options': {
'items': ['item1'],
'price': 1000,
'short': 'Short',
'description_md': 'Description',
'has_personal_diet': true,
},
'author': {'author_slug': 'author-slug', 'author_name': 'Author Name', 'author_profile_icon': 'https://example.com/icon.jpg', 'author_is_me': false},
'total_likes': 100,
'total_views': 1000,
'total_comments': 50,
'is_favorite': true,
'min_price_of_options': 1000.0,
'max_price_of_options': 3000.0,
'was_liked_by_me': true,
};
final model = PlanModel.fromJson(json);
expect(model.id, 1);
expect(model.slug, 'test-plan');
expect(model.name, 'Test Plan');
expect(model.duration, 30);
expect(model.state, 'active');
expect(model.type.fit, isTrue);
expect(model.packet1Options, isNotNull);
expect(model.packet1Options!.items, ['item1']);
expect(model.author.authorSlug, 'author-slug');
expect(model.totalLikes, 100);
expect(model.isFavorite, isTrue);
});
test('fromJson handles null packet options', () {
final json = {
'id': 1,
'slug': 'test-plan',
'name': 'Test Plan',
'image': 'https://example.com/image.jpg',
'duration': 30,
'state': 'active',
'type': {'fit': true, 'slim': false, 'behavior': false, 'wellness': false},
'description_md': 'Test description',
'packets_count': 3,
'packet1_options': null,
'packet2_options': null,
'packet3_options': null,
'author': {'author_slug': 'author-slug', 'author_name': 'Author Name', 'author_profile_icon': 'https://example.com/icon.jpg', 'author_is_me': false},
'total_likes': 100,
'total_views': 1000,
'total_comments': 50,
'is_favorite': true,
'min_price_of_options': 1000.0,
'max_price_of_options': 3000.0,
'was_liked_by_me': true,
};
final model = PlanModel.fromJson(json);
expect(model.packet1Options, isNull);
expect(model.packet2Options, isNull);
expect(model.packet3Options, isNull);
});
test('fromJson handles type as List (returns default PlanType)', () {
final json = {
'id': 1,
'slug': 'test-plan',
'name': 'Test Plan',
'image': 'https://example.com/image.jpg',
'duration': 30,
'state': 'active',
'type': [],
'description_md': 'Test description',
'packets_count': 3,
'author': {'author_slug': 'author-slug', 'author_name': 'Author Name', 'author_profile_icon': 'https://example.com/icon.jpg', 'author_is_me': false},
'total_likes': 100,
'total_views': 1000,
'total_comments': 50,
'is_favorite': true,
'min_price_of_options': 1000.0,
'max_price_of_options': 3000.0,
'was_liked_by_me': true,
};
final model = PlanModel.fromJson(json);
expect(model.type.fit, isFalse);
expect(model.type.slim, isFalse);
expect(model.type.behavior, isFalse);
expect(model.type.wellness, isFalse);
});
test('toJson serializes PlanModel correctly', () {
const model = PlanModel(
id: 1,
slug: 'test-plan',
name: 'Test Plan',
image: 'https://example.com/image.jpg',
duration: 30,
state: 'active',
type: PlanType(fit: true, slim: false, behavior: false, wellness: false),
details: 'Test description',
packetsCount: 3,
packet1Options: null,
packet2Options: null,
packet3Options: null,
author: Author(authorSlug: 'author-slug', authorName: 'Author Name', authorProfileIcon: 'https://example.com/icon.jpg', authorIsMe: false),
totalLikes: 100,
totalViews: 1000,
totalComments: 50,
isFavorite: true,
minPriceOfOptions: 1000.0,
maxPriceOfOptions: 3000.0,
wasLikedByMe: true,
);
final json = model.toJson();
expect(json['id'], 1);
expect(json['slug'], 'test-plan');
expect(json['name'], 'Test Plan');
expect(json['duration'], 30);
expect(json['state'], 'active');
expect(json['total_likes'], 100);
expect(json['is_favorite'], isTrue);
});
});
group('PlanPaginationModel', () {
test('fromJson parses all fields correctly', () {
final json = {
'data': [
{
'id': 1,
'slug': 'test-plan',
'name': 'Test Plan',
'image': 'https://example.com/image.jpg',
'duration': 30,
'state': 'active',
'type': {'fit': true, 'slim': false, 'behavior': false, 'wellness': false},
'description_md': 'Test description',
'packets_count': 3,
'author': {
'author_slug': 'author-slug',
'author_name': 'Author Name',
'author_profile_icon': 'https://example.com/icon.jpg',
'author_is_me': false,
},
'total_likes': 100,
'total_views': 1000,
'total_comments': 50,
'is_favorite': true,
'min_price_of_options': 1000.0,
'max_price_of_options': 3000.0,
'was_liked_by_me': true,
},
],
'links': {'first': 'https://example.com/first', 'last': 'https://example.com/last', 'prev': null, 'next': 'https://example.com/next'},
'meta': {'current_page': 1, 'last_page': 10, 'per_page': 20, 'total': 200, 'from': null, 'to': null, 'links': []},
};
final model = PlanPaginationModel.fromJson(json);
expect(model.data.length, 1);
expect(model.data.first.id, 1);
expect(model.data.first.name, 'Test Plan');
expect(model.links.first, 'https://example.com/first');
expect(model.meta.currentPage, 1);
expect(model.meta.lastPage, 10);
});
test('toJson serializes PlanPaginationModel correctly', () {
const planModel = PlanModel(
id: 1,
slug: 'test-plan',
name: 'Test Plan',
image: 'https://example.com/image.jpg',
duration: 30,
state: 'active',
type: PlanType(fit: true, slim: false, behavior: false, wellness: false),
details: 'Test description',
packetsCount: 3,
packet1Options: null,
packet2Options: null,
packet3Options: null,
author: Author(authorSlug: 'author-slug', authorName: 'Author Name', authorProfileIcon: 'https://example.com/icon.jpg', authorIsMe: false),
totalLikes: 100,
totalViews: 1000,
totalComments: 50,
isFavorite: true,
minPriceOfOptions: 1000.0,
maxPriceOfOptions: 3000.0,
wasLikedByMe: true,
);
const model = PlanPaginationModel(
data: [planModel],
links: Links(first: 'https://example.com/first', last: 'https://example.com/last', prev: null, next: 'https://example.com/next'),
meta: Meta(currentPage: 1, lastPage: 10, perPage: 20, total: 200, from: null, to: null, links: []),
);
final json = model.toJson();
expect(json.containsKey('data'), isTrue);
expect((json['data'] as List).length, 1);
expect(json.containsKey('links'), isTrue);
expect(json.containsKey('meta'), isTrue);
});
});
}

View File

@@ -233,6 +233,119 @@ void main() {
expect(step.image, 'step1.jpg');
expect(step.description, 'Step description');
});
test('toJson serializes Step correctly', () {
const step = Step(
image: 'step1.jpg',
description: 'Step description',
);
final json = step.toJson();
expect(json['image'], 'step1.jpg');
expect(json['description_md'], 'Step description');
});
});
group('Recipe', () {
test('toJson serializes Recipe correctly', () {
const author = Author(
authorSlug: 'chef',
authorName: 'Chef Name',
authorProfileIcon: 'icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: false,
authorPlaceInRating: null,
);
final ingredients = [
const Ingredient(name: 'Flour', unit: 'cup', portion: '1', productId: 1),
];
final steps = [
const Step(image: 'step1.jpg', description: 'Step 1 description'),
];
final recipe = Recipe(
id: 1,
image: 'recipe.jpg',
state: 'published',
cookingTime: 30,
activeCookingTime: 15,
ingredients: ingredients,
description: 'Recipe description',
steps: steps,
videoUrl: 'video.mp4',
createdAt: DateTime(2023, 1, 1),
updatedAt: DateTime(2023, 1, 2),
title: 'Test Recipe',
type: 'main',
slug: 'test-recipe',
commentsCount: 5,
wasLikedByMe: false,
isFavorite: false,
calories: 250.0,
servings: 4,
likesCount: 10,
viewsCount: 100,
tags: [const Tag(name: 'sweet')],
author: author,
);
final json = recipe.toJson();
expect(json['id'], 1);
expect(json['title'], 'Test Recipe');
expect(json['slug'], 'test-recipe');
expect(json['cooking_time'], 30);
expect(json['energy_per_serving'], 250.0);
expect(json.containsKey('ingredients'), isTrue);
expect(json.containsKey('steps'), isTrue);
expect(json.containsKey('tags'), isTrue);
});
});
group('Tag', () {
test('toJson serializes Tag correctly', () {
const tag = Tag(name: 'dessert');
final json = tag.toJson();
expect(json['name'], 'dessert');
});
});
group('Ingredient', () {
test('toJson serializes Ingredient correctly', () {
const ingredient = Ingredient(
name: 'Flour',
unit: 'cup',
portion: '1',
productId: 1,
);
final json = ingredient.toJson();
expect(json['name'], 'Flour');
expect(json['unit'], 'cup');
expect(json['portion'], '1');
expect(json['product_nutritional_id'], 1);
});
test('toJson serializes Ingredient with null unit correctly', () {
const ingredient = Ingredient(
name: 'Salt',
unit: null,
portion: 'pinch',
productId: 2,
);
final json = ingredient.toJson();
expect(json['name'], 'Salt');
expect(json['unit'], isNull);
expect(json['portion'], 'pinch');
});
});
}

View File

@@ -96,5 +96,54 @@ void main() {
expect(pagination.recipesList.length, 1);
expect(pagination.recipesList[0].id, 1);
});
test('toJson serializes RecipesPagination correctly', () {
const author = Author(
authorSlug: 'chef',
authorName: 'Chef',
authorProfileIcon: 'photo.jpg',
authorIsMe: false,
isEntitySubscribedByMe: false,
authorPlaceInRating: null,
);
final recipes = [
const Recipe(
id: 1,
image: 'image1.jpg',
state: 'published',
cookingTime: 30,
activeCookingTime: 15,
ingredients: null,
description: 'Test recipe 1',
steps: null,
videoUrl: null,
createdAt: null,
updatedAt: null,
title: 'Recipe 1',
type: 'main',
slug: 'recipe-1',
commentsCount: 5,
wasLikedByMe: false,
isFavorite: false,
calories: 250.0,
servings: 4,
likesCount: 10,
viewsCount: 100,
tags: [],
author: author,
),
];
final pagination = RecipesPagination(recipesList: recipes);
final json = pagination.toJson();
expect(json.containsKey('data'), isTrue);
expect((json['data'] as List).length, 1);
final firstRecipe = (json['data'] as List).first;
expect(firstRecipe, isA<Recipe>());
expect((firstRecipe as Recipe).id, 1);
});
});
}

View File

@@ -3,40 +3,54 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('ViewModel', () {
test('создает ViewModel с правильными значениями', () {
final model = ViewModel(
type: 'blog_posts',
ids: [1, 2, 3],
slugs: null,
);
expect(model.type, 'blog_posts');
expect(model.ids, [1, 2, 3]);
expect(model.slugs, isNull);
});
test('создает ViewModel с slugs', () {
final model = ViewModel(
type: 'plans',
ids: null,
slugs: ['plan-1', 'plan-2'],
);
expect(model.type, 'plans');
expect(model.slugs, ['plan-1', 'plan-2']);
});
test('fromJson создает ViewModel из JSON', () {
test('fromJson parses all fields correctly', () {
final json = {
'type': 'diets',
'ids': [1, 2],
'type': 'diet',
'ids': [1, 2, 3],
'slugs': ['diet-1', 'diet-2'],
};
final model = ViewModel.fromJson(json);
expect(model.type, 'diets');
expect(model.ids, [1, 2]);
expect(model.type, 'diet');
expect(model.ids, [1, 2, 3]);
expect(model.slugs, ['diet-1', 'diet-2']);
});
test('fromJson handles null optional fields', () {
final json = {
'type': 'plan',
};
final model = ViewModel.fromJson(json);
expect(model.type, 'plan');
expect(model.ids, isNull);
expect(model.slugs, isNull);
});
test('toJson serializes all fields correctly', () {
final model = ViewModel(
type: 'recipe',
ids: [1, 2],
slugs: ['recipe-1'],
);
final json = model.toJson();
expect(json['type'], 'recipe');
expect(json['ids'], [1, 2]);
expect(json['slugs'], ['recipe-1']);
});
test('toJson omits null fields', () {
final model = ViewModel(type: 'diet');
final json = model.toJson();
expect(json['type'], 'diet');
expect(json.containsKey('ids'), isTrue);
expect(json.containsKey('slugs'), isTrue);
});
});
}