forked from eatvio/eatvio_app
417 lines
12 KiB
Dart
417 lines
12 KiB
Dart
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
|
|
import 'package:eatvio_app/features/feed/models/recipes_model.dart';
|
|
import 'package:eatvio_app/features/recipe/models/my_recipe_model.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
void main() {
|
|
group('MyRecipePaginationModel', () {
|
|
test('creates MyRecipePaginationModel with empty list', () {
|
|
const model = MyRecipePaginationModel(data: []);
|
|
|
|
expect(model.data, isEmpty);
|
|
});
|
|
|
|
test('creates MyRecipePaginationModel with recipes', () {
|
|
final recipes = [
|
|
const MyRecipeModel(
|
|
id: 1,
|
|
image: 'image1.jpg',
|
|
state: 'published',
|
|
cookingTime: 30,
|
|
activeCookingTime: 15,
|
|
description: 'Test recipe 1',
|
|
steps: null,
|
|
videoUrl: null,
|
|
title: 'Recipe 1',
|
|
slug: 'recipe-1',
|
|
calories: 250.0,
|
|
likesCount: 10,
|
|
viewsCount: 100,
|
|
),
|
|
const MyRecipeModel(
|
|
id: 2,
|
|
image: 'image2.jpg',
|
|
state: 'draft',
|
|
cookingTime: 45,
|
|
activeCookingTime: 20,
|
|
description: 'Test recipe 2',
|
|
steps: null,
|
|
videoUrl: 'video.mp4',
|
|
title: 'Recipe 2',
|
|
slug: 'recipe-2',
|
|
calories: 300.0,
|
|
likesCount: 5,
|
|
viewsCount: 50,
|
|
),
|
|
];
|
|
|
|
final model = MyRecipePaginationModel(data: recipes);
|
|
|
|
expect(model.data.length, 2);
|
|
expect(model.data[0].id, 1);
|
|
expect(model.data[0].title, 'Recipe 1');
|
|
expect(model.data[1].id, 2);
|
|
expect(model.data[1].title, 'Recipe 2');
|
|
});
|
|
|
|
test('creates MyRecipePaginationModel from JSON', () {
|
|
final json = {
|
|
'data': [
|
|
{
|
|
'id': 1,
|
|
'image': 'image1.jpg',
|
|
'state': 'published',
|
|
'cooking_time': 30,
|
|
'active_time': 15,
|
|
'description_md': 'Test recipe',
|
|
'steps': null,
|
|
'video_url': null,
|
|
'title': 'Recipe 1',
|
|
'slug': 'recipe-1',
|
|
'energy_per_serving': 250.0,
|
|
'total_likes': 10,
|
|
'total_views': 100,
|
|
},
|
|
],
|
|
};
|
|
|
|
final model = MyRecipePaginationModel.fromJson(json);
|
|
|
|
expect(model.data.length, 1);
|
|
expect(model.data[0].id, 1);
|
|
expect(model.data[0].title, 'Recipe 1');
|
|
});
|
|
});
|
|
|
|
group('MyRecipeModel', () {
|
|
test('creates MyRecipeModel with all parameters', () {
|
|
const recipe = MyRecipeModel(
|
|
id: 1,
|
|
image: 'image.jpg',
|
|
state: 'published',
|
|
cookingTime: 30,
|
|
activeCookingTime: 15,
|
|
description: 'Test recipe',
|
|
steps: null,
|
|
videoUrl: null,
|
|
title: 'Recipe 1',
|
|
slug: 'recipe-1',
|
|
calories: 250.0,
|
|
likesCount: 10,
|
|
viewsCount: 100,
|
|
);
|
|
|
|
expect(recipe.id, 1);
|
|
expect(recipe.image, 'image.jpg');
|
|
expect(recipe.state, 'published');
|
|
expect(recipe.cookingTime, 30);
|
|
expect(recipe.activeCookingTime, 15);
|
|
expect(recipe.description, 'Test recipe');
|
|
expect(recipe.steps, null);
|
|
expect(recipe.videoUrl, null);
|
|
expect(recipe.title, 'Recipe 1');
|
|
expect(recipe.slug, 'recipe-1');
|
|
expect(recipe.calories, 250.0);
|
|
expect(recipe.likesCount, 10);
|
|
expect(recipe.viewsCount, 100);
|
|
});
|
|
|
|
test('creates MyRecipeModel with steps and videoUrl', () {
|
|
final steps = [const Step(image: 'step1.jpg', description: 'Step 1'), const Step(image: 'step2.jpg', description: 'Step 2')];
|
|
|
|
final recipe = MyRecipeModel(
|
|
id: 1,
|
|
image: 'image.jpg',
|
|
state: 'published',
|
|
cookingTime: 30,
|
|
activeCookingTime: 15,
|
|
description: 'Test recipe',
|
|
steps: steps,
|
|
videoUrl: 'video.mp4',
|
|
title: 'Recipe 1',
|
|
slug: 'recipe-1',
|
|
calories: 250.0,
|
|
likesCount: 10,
|
|
viewsCount: 100,
|
|
);
|
|
|
|
expect(recipe.steps, isNotNull);
|
|
expect(recipe.steps!.length, 2);
|
|
expect(recipe.videoUrl, 'video.mp4');
|
|
});
|
|
|
|
test('creates MyRecipeModel from JSON', () {
|
|
final json = {
|
|
'id': 1,
|
|
'image': 'image.jpg',
|
|
'state': 'published',
|
|
'cooking_time': 30,
|
|
'active_time': 15,
|
|
'description_md': 'Test recipe',
|
|
'steps': null,
|
|
'video_url': null,
|
|
'title': 'Recipe 1',
|
|
'slug': 'recipe-1',
|
|
'energy_per_serving': 250.0,
|
|
'total_likes': 10,
|
|
'total_views': 100,
|
|
};
|
|
|
|
final recipe = MyRecipeModel.fromJson(json);
|
|
|
|
expect(recipe.id, 1);
|
|
expect(recipe.title, 'Recipe 1');
|
|
expect(recipe.cookingTime, 30);
|
|
expect(recipe.calories, 250.0);
|
|
});
|
|
|
|
test('toJson serializes MyRecipeModel correctly', () {
|
|
const recipe = MyRecipeModel(
|
|
id: 1,
|
|
image: 'image.jpg',
|
|
state: 'published',
|
|
cookingTime: 30,
|
|
activeCookingTime: 15,
|
|
description: 'Test recipe',
|
|
steps: null,
|
|
videoUrl: null,
|
|
title: 'Recipe 1',
|
|
slug: 'recipe-1',
|
|
calories: 250.0,
|
|
likesCount: 10,
|
|
viewsCount: 100,
|
|
);
|
|
|
|
final json = recipe.toJson();
|
|
|
|
expect(json['id'], 1);
|
|
expect(json['title'], 'Recipe 1');
|
|
expect(json['slug'], 'recipe-1');
|
|
expect(json['cooking_time'], 30);
|
|
expect(json['active_time'], 15);
|
|
expect(json['energy_per_serving'], 250.0);
|
|
expect(json['total_likes'], 10);
|
|
expect(json['total_views'], 100);
|
|
});
|
|
});
|
|
|
|
group('MyRecipePaginationModel', () {
|
|
test('toJson serializes MyRecipePaginationModel correctly', () {
|
|
final recipes = [
|
|
const MyRecipeModel(
|
|
id: 1,
|
|
image: 'image1.jpg',
|
|
state: 'published',
|
|
cookingTime: 30,
|
|
activeCookingTime: 15,
|
|
description: 'Test recipe 1',
|
|
steps: null,
|
|
videoUrl: null,
|
|
title: 'Recipe 1',
|
|
slug: 'recipe-1',
|
|
calories: 250.0,
|
|
likesCount: 10,
|
|
viewsCount: 100,
|
|
),
|
|
];
|
|
|
|
final model = MyRecipePaginationModel(data: recipes);
|
|
|
|
final json = model.toJson();
|
|
|
|
expect(json.containsKey('data'), isTrue);
|
|
expect((json['data'] as List).length, 1);
|
|
});
|
|
});
|
|
|
|
group('MyRecipeModelX.toRecipeModel', () {
|
|
test('maps fields and uses fixed state, empty ingredients/tags', () {
|
|
const recipe = MyRecipeModel(
|
|
id: 7,
|
|
image: 'image.jpg',
|
|
state: 'draft',
|
|
cookingTime: 30,
|
|
activeCookingTime: 15,
|
|
description: 'Some description',
|
|
steps: [
|
|
Step(image: 's1.jpg', description: 'Step 1'),
|
|
Step(image: 's2.jpg', description: 'Step 2'),
|
|
],
|
|
videoUrl: 'video.mp4',
|
|
title: 'Recipe',
|
|
slug: 'recipe',
|
|
calories: 250.7,
|
|
likesCount: 1,
|
|
viewsCount: 2,
|
|
);
|
|
|
|
final result = recipe.toRecipeModel();
|
|
|
|
expect(result.title, 'Recipe');
|
|
expect(result.description, 'Some description');
|
|
expect(result.image, 'image.jpg');
|
|
expect(result.totalCookingTime, 30);
|
|
expect(result.activeCookTime, 15);
|
|
expect(result.energyPerServing, 250);
|
|
expect(result.videoUrl, 'video.mp4');
|
|
expect(result.state, 'active');
|
|
expect(result.steps, isNotNull);
|
|
expect(result.steps!.length, 2);
|
|
expect(result.steps![0]!.image, 's1.jpg');
|
|
expect(result.steps![0]!.description, 'Step 1');
|
|
expect(result.ingredients, isEmpty);
|
|
expect(result.tags, isEmpty);
|
|
});
|
|
|
|
test('handles null steps gracefully', () {
|
|
const recipe = MyRecipeModel(
|
|
id: 1,
|
|
image: 'image.jpg',
|
|
state: 'draft',
|
|
cookingTime: 10,
|
|
activeCookingTime: 5,
|
|
description: 'desc',
|
|
steps: null,
|
|
videoUrl: null,
|
|
title: 'r',
|
|
slug: 'r',
|
|
calories: 100.0,
|
|
likesCount: 0,
|
|
viewsCount: 0,
|
|
);
|
|
|
|
final result = recipe.toRecipeModel();
|
|
|
|
expect(result.steps, isNull);
|
|
expect(result.videoUrl, isNull);
|
|
});
|
|
});
|
|
|
|
group('MyRecipeModelX.toRecipe', () {
|
|
test('maps required Recipe fields and applies defaults', () {
|
|
const recipe = MyRecipeModel(
|
|
id: 11,
|
|
image: 'image.jpg',
|
|
state: 'published',
|
|
cookingTime: 45,
|
|
activeCookingTime: 20,
|
|
description: 'desc',
|
|
steps: [Step(image: 's.jpg', description: 'step')],
|
|
videoUrl: 'video.mp4',
|
|
title: 'Title',
|
|
slug: 'title',
|
|
calories: 333.0,
|
|
likesCount: 7,
|
|
viewsCount: 8,
|
|
);
|
|
|
|
final result = recipe.toRecipe();
|
|
|
|
expect(result.id, 11);
|
|
expect(result.image, 'image.jpg');
|
|
expect(result.state, 'published');
|
|
expect(result.cookingTime, 45);
|
|
expect(result.activeCookingTime, 20);
|
|
expect(result.description, 'desc');
|
|
expect(result.steps, isNotNull);
|
|
expect(result.steps!.length, 1);
|
|
expect(result.videoUrl, 'video.mp4');
|
|
expect(result.title, 'Title');
|
|
expect(result.slug, 'title');
|
|
expect(result.calories, 333.0);
|
|
expect(result.likesCount, 7);
|
|
expect(result.viewsCount, 8);
|
|
expect(result.type, 'recipe');
|
|
expect(result.commentsCount, 0);
|
|
expect(result.wasLikedByMe, isFalse);
|
|
expect(result.isFavorite, isFalse);
|
|
expect(result.tags, isEmpty);
|
|
expect(result.ingredients, isEmpty);
|
|
expect(result.author.authorIsMe, isTrue);
|
|
expect(result.author.authorSlug, '');
|
|
});
|
|
});
|
|
|
|
group('RecipeToRecipeModelX.toRecipeModel', () {
|
|
test('maps Recipe to RecipeModel including ingredients and tags', () {
|
|
const recipe = Recipe(
|
|
id: 1,
|
|
image: 'image.jpg',
|
|
state: 'draft',
|
|
cookingTime: 30,
|
|
activeCookingTime: 15,
|
|
ingredients: [
|
|
Ingredient(name: 'Salt', unit: 'g', portion: '5', productId: 1),
|
|
Ingredient(name: 'Sugar', unit: null, portion: '10', productId: 2),
|
|
],
|
|
description: 'desc',
|
|
steps: [Step(image: 's.jpg', description: 'step')],
|
|
videoUrl: 'video.mp4',
|
|
title: 'Title',
|
|
type: 'recipe',
|
|
slug: 'slug',
|
|
commentsCount: 1,
|
|
wasLikedByMe: false,
|
|
isFavorite: false,
|
|
calories: 200.6,
|
|
likesCount: 3,
|
|
viewsCount: 4,
|
|
tags: [
|
|
Tag(name: 'fast'),
|
|
Tag(name: 'vegetarian'),
|
|
],
|
|
author: Author(authorSlug: 'a', authorName: 'A', authorProfileIcon: '', authorIsMe: true),
|
|
);
|
|
|
|
final result = recipe.toRecipeModel();
|
|
|
|
expect(result.title, 'Title');
|
|
expect(result.description, 'desc');
|
|
expect(result.image, 'image.jpg');
|
|
expect(result.totalCookingTime, 30);
|
|
expect(result.activeCookTime, 15);
|
|
expect(result.energyPerServing, 200);
|
|
expect(result.videoUrl, 'video.mp4');
|
|
expect(result.state, 'active');
|
|
expect(result.steps, isNotNull);
|
|
expect(result.steps!.length, 1);
|
|
expect(result.ingredients!.length, 2);
|
|
expect(result.ingredients![0]!.name, 'Salt');
|
|
expect(result.ingredients![0]!.unit, 'g');
|
|
expect(result.ingredients![1]!.unit, '');
|
|
expect(result.tags, ['fast', 'vegetarian']);
|
|
});
|
|
|
|
test('returns empty ingredients when source is null', () {
|
|
const recipe = Recipe(
|
|
id: 1,
|
|
image: 'image.jpg',
|
|
state: 'draft',
|
|
cookingTime: 1,
|
|
activeCookingTime: 1,
|
|
ingredients: null,
|
|
description: 'desc',
|
|
steps: null,
|
|
videoUrl: null,
|
|
title: 't',
|
|
type: 'recipe',
|
|
slug: 's',
|
|
commentsCount: 0,
|
|
wasLikedByMe: false,
|
|
isFavorite: false,
|
|
calories: 1.0,
|
|
likesCount: 0,
|
|
viewsCount: 0,
|
|
tags: [],
|
|
author: Author(authorSlug: '', authorName: '', authorProfileIcon: '', authorIsMe: false),
|
|
);
|
|
|
|
final result = recipe.toRecipeModel();
|
|
|
|
expect(result.ingredients, isEmpty);
|
|
expect(result.tags, isEmpty);
|
|
expect(result.steps, isNull);
|
|
});
|
|
});
|
|
}
|