All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 57m53s
544 lines
20 KiB
TypeScript
544 lines
20 KiB
TypeScript
// src/tests/utils/mockFactories.ts
|
|
import { UserProfile, User, Flyer, Store, SuggestedCorrection, Brand, FlyerItem, MasterGroceryItem, ShoppingList, ShoppingListItem, Achievement, UserAchievement, Budget, SpendingByCategory, Recipe, RecipeComment, ActivityLogItem, DietaryRestriction, Appliance, Notification, UnmatchedFlyerItem, AdminUserView, WatchedItemDeal, LeaderboardUser, UserWithPasswordHash, Profile, Address } from '../../types';
|
|
|
|
/**
|
|
* Creates a mock UserProfile object for use in tests, ensuring type safety.
|
|
*
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* This allows for easy customization of the mock user for specific test cases.
|
|
* For example: `createMockUserProfile({ role: 'admin', points: 500 })`
|
|
* @returns A complete and type-safe UserProfile object.
|
|
*/
|
|
export const createMockUserProfile = (overrides: Partial<UserProfile & { user: Partial<User> }> = {}): UserProfile => {
|
|
const userId = overrides.user_id ?? `user-${Math.random().toString(36).substring(2, 9)}`;
|
|
|
|
const defaultProfile: UserProfile = {
|
|
user_id: userId,
|
|
role: 'user',
|
|
points: 0,
|
|
full_name: 'Test User',
|
|
avatar_url: null,
|
|
preferences: {},
|
|
address: null,
|
|
user: {
|
|
user_id: userId,
|
|
email: `${userId}@example.com`,
|
|
...overrides.user, // Apply nested user overrides
|
|
},
|
|
};
|
|
|
|
return { ...defaultProfile, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock Flyer object for use in tests, ensuring type safety.
|
|
*
|
|
* @param overrides - An object containing properties to override the default mock values,
|
|
* including nested properties for the `store`.
|
|
* e.g., `createMockFlyer({ item_count: 50, store: { name: 'Walmart' } })`
|
|
* @returns A complete and type-safe Flyer object.
|
|
*/
|
|
export const createMockFlyer = (overrides: Partial<Flyer & { store: Partial<Store> }> = {}): Flyer => {
|
|
const flyerId = overrides.flyer_id ?? Math.floor(Math.random() * 1000);
|
|
const storeId = overrides.store?.store_id ?? Math.floor(Math.random() * 100);
|
|
|
|
const defaultFlyer: Flyer = {
|
|
flyer_id: flyerId,
|
|
created_at: new Date().toISOString(),
|
|
file_name: `flyer-${flyerId}.jpg`,
|
|
image_url: `/flyer-images/flyer-${flyerId}.jpg`,
|
|
icon_url: `/flyer-images/icons/icon-flyer-${flyerId}.webp`,
|
|
checksum: `checksum-${flyerId}`,
|
|
store_id: storeId,
|
|
valid_from: new Date().toISOString().split('T')[0],
|
|
valid_to: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], // 7 days from now
|
|
store_address: '123 Main St, Anytown, USA',
|
|
item_count: Math.floor(Math.random() * 100) + 10,
|
|
uploaded_by: null,
|
|
store: {
|
|
store_id: storeId,
|
|
created_at: new Date().toISOString(),
|
|
name: 'Mock Store',
|
|
logo_url: null,
|
|
},
|
|
};
|
|
|
|
// Deep merge the store object and then merge the top-level properties.
|
|
return { ...defaultFlyer, ...overrides, store: { ...defaultFlyer.store, ...overrides.store } as Store };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock SuggestedCorrection object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe SuggestedCorrection object.
|
|
*/
|
|
export const createMockSuggestedCorrection = (overrides: Partial<SuggestedCorrection> = {}): SuggestedCorrection => {
|
|
const defaultCorrection: SuggestedCorrection = {
|
|
suggested_correction_id: Math.floor(Math.random() * 1000),
|
|
flyer_item_id: Math.floor(Math.random() * 10000),
|
|
user_id: `user-${Math.random().toString(36).substring(2, 9)}`,
|
|
correction_type: 'price',
|
|
suggested_value: '$9.99',
|
|
status: 'pending',
|
|
created_at: new Date().toISOString(),
|
|
};
|
|
|
|
return { ...defaultCorrection, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock Brand object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe Brand object.
|
|
*/
|
|
export const createMockBrand = (overrides: Partial<Brand> = {}): Brand => {
|
|
const brandId = overrides.brand_id ?? Math.floor(Math.random() * 100);
|
|
|
|
const defaultBrand: Brand = {
|
|
brand_id: brandId,
|
|
name: `Brand ${brandId}`,
|
|
logo_url: null,
|
|
store_id: null,
|
|
store_name: null,
|
|
};
|
|
|
|
return { ...defaultBrand, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock FlyerItem object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe FlyerItem object.
|
|
*/
|
|
export const createMockFlyerItem = (overrides: Partial<FlyerItem> = {}): FlyerItem => {
|
|
const defaultItem: FlyerItem = {
|
|
flyer_item_id: Math.floor(Math.random() * 10000),
|
|
flyer_id: Math.floor(Math.random() * 1000),
|
|
created_at: new Date().toISOString(),
|
|
item: 'Mock Item',
|
|
price_display: '$1.99',
|
|
price_in_cents: 199,
|
|
quantity: 'each',
|
|
view_count: 0,
|
|
click_count: 0,
|
|
updated_at: new Date().toISOString(),
|
|
};
|
|
|
|
return { ...defaultItem, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock Recipe object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe Recipe object.
|
|
*/
|
|
export const createMockRecipe = (overrides: Partial<Recipe> = {}): Recipe => {
|
|
const recipeId = overrides.recipe_id ?? Math.floor(Math.random() * 1000);
|
|
|
|
const defaultRecipe: Recipe = {
|
|
recipe_id: recipeId,
|
|
user_id: `user-${Math.random().toString(36).substring(2, 9)}`,
|
|
name: `Mock Recipe ${recipeId}`,
|
|
description: 'A delicious mock recipe.',
|
|
instructions: '1. Mock the ingredients. 2. Mock the cooking. 3. Enjoy!',
|
|
avg_rating: Math.random() * 5,
|
|
rating_count: Math.floor(Math.random() * 100),
|
|
fork_count: Math.floor(Math.random() * 20),
|
|
status: 'public',
|
|
created_at: new Date().toISOString(),
|
|
prep_time_minutes: 15,
|
|
cook_time_minutes: 30,
|
|
servings: 4,
|
|
};
|
|
|
|
return { ...defaultRecipe, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock RecipeComment object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe RecipeComment object.
|
|
*/
|
|
export const createMockRecipeComment = (overrides: Partial<RecipeComment> = {}): RecipeComment => {
|
|
const defaultComment: RecipeComment = {
|
|
recipe_comment_id: Math.floor(Math.random() * 10000),
|
|
recipe_id: Math.floor(Math.random() * 1000),
|
|
user_id: `user-${Math.random().toString(36).substring(2, 9)}`,
|
|
content: 'This is a mock comment.',
|
|
status: 'visible',
|
|
created_at: new Date().toISOString(),
|
|
user_full_name: 'Mock User', // This was correct
|
|
user_avatar_url: undefined,
|
|
};
|
|
|
|
return { ...defaultComment, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock ActivityLogItem object for use in tests.
|
|
* This factory handles the discriminated union nature of the ActivityLogItem type.
|
|
* By default, it creates a 'flyer_processed' log item. You can override the 'action'
|
|
* and 'details' to create other types of log items.
|
|
*
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* e.g., `createMockActivityLogItem({ action: 'user_registered', details: { full_name: 'New User' } })`
|
|
* @returns A complete and type-safe ActivityLogItem object.
|
|
*/
|
|
export const createMockActivityLogItem = (overrides: Partial<ActivityLogItem> = {}): ActivityLogItem => {
|
|
const action = overrides.action ?? 'flyer_processed';
|
|
|
|
const baseLog = {
|
|
activity_log_id: Math.floor(Math.random() * 10000),
|
|
user_id: `user-${Math.random().toString(36).substring(2, 9)}`,
|
|
created_at: new Date().toISOString(),
|
|
};
|
|
|
|
let specificLog: ActivityLogItem;
|
|
|
|
// Create a default log based on the action, which can then be overridden.
|
|
switch (action) {
|
|
case 'recipe_created':
|
|
specificLog = {
|
|
...baseLog,
|
|
action: 'recipe_created',
|
|
display_text: 'Created a new recipe: Mock Recipe.',
|
|
icon: 'chef-hat',
|
|
details: { recipe_id: 1, recipe_name: 'Mock Recipe' },
|
|
};
|
|
break;
|
|
case 'user_registered':
|
|
specificLog = {
|
|
...baseLog,
|
|
action: 'user_registered',
|
|
display_text: 'A new user has registered.',
|
|
icon: 'user-plus',
|
|
details: { full_name: 'New Mock User' },
|
|
};
|
|
break;
|
|
case 'list_shared':
|
|
specificLog = {
|
|
...baseLog,
|
|
action: 'list_shared',
|
|
display_text: 'A shopping list was shared.',
|
|
icon: 'share-2',
|
|
details: { list_name: 'Mock List', shopping_list_id: 1, shared_with_name: 'Another User' },
|
|
};
|
|
break;
|
|
case 'flyer_processed':
|
|
default:
|
|
specificLog = {
|
|
...baseLog,
|
|
action: 'flyer_processed',
|
|
display_text: 'Processed a new flyer for Mock Store.',
|
|
icon: 'file-check',
|
|
details: { flyer_id: 1, store_name: 'Mock Store' },
|
|
};
|
|
break;
|
|
}
|
|
|
|
// Merge the generated log with any specific overrides provided.
|
|
// This allows for deep merging of the 'details' object.
|
|
return { ...specificLog, ...overrides, details: { ...specificLog.details, ...overrides.details } } as ActivityLogItem;
|
|
};
|
|
|
|
/**
|
|
* Creates a mock Achievement object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe Achievement object.
|
|
*/
|
|
export const createMockAchievement = (overrides: Partial<Achievement> = {}): Achievement => {
|
|
const defaultAchievement: Achievement = {
|
|
achievement_id: Math.floor(Math.random() * 100),
|
|
name: 'Mock Achievement',
|
|
description: 'A great accomplishment.',
|
|
icon: 'star',
|
|
points_value: 10,
|
|
};
|
|
return { ...defaultAchievement, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock object representing a joined UserAchievement and Achievement for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe object representing the joined achievement data.
|
|
*/
|
|
export const createMockUserAchievement = (overrides: Partial<UserAchievement & Achievement> = {}): UserAchievement & Achievement => {
|
|
const achievementId = overrides.achievement_id ?? Math.floor(Math.random() * 100);
|
|
const defaultUserAchievement: UserAchievement & Achievement = {
|
|
user_id: `user-${Math.random().toString(36).substring(2, 9)}`,
|
|
achievement_id: achievementId,
|
|
achieved_at: new Date().toISOString(),
|
|
// from Achievement
|
|
name: 'Mock User Achievement',
|
|
description: 'An achievement someone earned.',
|
|
icon: 'award',
|
|
points_value: 20,
|
|
};
|
|
return { ...defaultUserAchievement, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock Budget object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe Budget object.
|
|
*/
|
|
export const createMockBudget = (overrides: Partial<Budget> = {}): Budget => {
|
|
const defaultBudget: Budget = {
|
|
budget_id: Math.floor(Math.random() * 100),
|
|
user_id: `user-${Math.random().toString(36).substring(2, 9)}`,
|
|
name: 'Monthly Groceries',
|
|
amount_cents: 50000,
|
|
period: 'monthly',
|
|
start_date: new Date().toISOString().split('T')[0],
|
|
};
|
|
return { ...defaultBudget, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock SpendingByCategory object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe SpendingByCategory object.
|
|
*/
|
|
export const createMockSpendingByCategory = (overrides: Partial<SpendingByCategory> = {}): SpendingByCategory => {
|
|
const defaultSpending: SpendingByCategory = {
|
|
category_id: Math.floor(Math.random() * 20) + 1,
|
|
category_name: 'Produce',
|
|
total_spent_cents: Math.floor(Math.random() * 20000) + 1000,
|
|
};
|
|
return { ...defaultSpending, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock MasterGroceryItem object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe MasterGroceryItem object.
|
|
*/
|
|
export const createMockMasterGroceryItem = (overrides: Partial<MasterGroceryItem> = {}): MasterGroceryItem => {
|
|
const defaultItem: MasterGroceryItem = {
|
|
master_grocery_item_id: Math.floor(Math.random() * 10000),
|
|
created_at: new Date().toISOString(),
|
|
name: 'Mock Master Item',
|
|
category_id: 1,
|
|
category_name: 'Pantry & Dry Goods',
|
|
};
|
|
|
|
return { ...defaultItem, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock ShoppingList object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe ShoppingList object.
|
|
*/
|
|
export const createMockShoppingList = (overrides: Partial<ShoppingList> = {}): ShoppingList => {
|
|
const defaultList: ShoppingList = {
|
|
shopping_list_id: Math.floor(Math.random() * 100),
|
|
user_id: `user-${Math.random().toString(36).substring(2, 9)}`,
|
|
name: 'My Mock List',
|
|
created_at: new Date().toISOString(),
|
|
items: [],
|
|
};
|
|
|
|
return { ...defaultList, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock ShoppingListItem object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe ShoppingListItem object.
|
|
*/
|
|
export const createMockShoppingListItem = (overrides: Partial<ShoppingListItem> = {}): ShoppingListItem => {
|
|
const defaultItem: ShoppingListItem = {
|
|
shopping_list_item_id: Math.floor(Math.random() * 100000),
|
|
shopping_list_id: Math.floor(Math.random() * 100),
|
|
custom_item_name: 'Mock Shopping List Item',
|
|
quantity: 1,
|
|
is_purchased: false,
|
|
added_at: new Date().toISOString(),
|
|
};
|
|
|
|
return { ...defaultItem, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock DietaryRestriction object for testing.
|
|
* @param overrides - Optional properties to override the defaults.
|
|
* @returns A mock DietaryRestriction object.
|
|
*/
|
|
export const createMockDietaryRestriction = (overrides: Partial<DietaryRestriction> = {}): DietaryRestriction => {
|
|
return {
|
|
dietary_restriction_id: 1,
|
|
name: 'Vegetarian',
|
|
type: 'diet',
|
|
...overrides,
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Creates a mock Address object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe Address object.
|
|
*/
|
|
export const createMockAddress = (overrides: Partial<Address> = {}): Address => {
|
|
const defaultAddress: Address = {
|
|
address_id: Math.floor(Math.random() * 1000),
|
|
address_line_1: '123 Mock St',
|
|
city: 'Mockville',
|
|
province_state: 'BC',
|
|
postal_code: 'V8T 1A1',
|
|
country: 'CA',
|
|
created_at: new Date().toISOString(),
|
|
updated_at: new Date().toISOString(),
|
|
// Optional fields
|
|
address_line_2: null,
|
|
latitude: null,
|
|
longitude: null,
|
|
location: null,
|
|
};
|
|
|
|
return { ...defaultAddress, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock UserWithPasswordHash object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe UserWithPasswordHash object.
|
|
*/
|
|
export const createMockUserWithPasswordHash = (overrides: Partial<UserWithPasswordHash> = {}): UserWithPasswordHash => {
|
|
const userId = overrides.user_id ?? `user-${Math.random().toString(36).substring(2, 9)}`;
|
|
|
|
const defaultUser: UserWithPasswordHash = {
|
|
user_id: userId,
|
|
email: `${userId}@example.com`,
|
|
password_hash: 'hashed_password',
|
|
failed_login_attempts: 0,
|
|
last_failed_login: null,
|
|
};
|
|
|
|
return { ...defaultUser, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock Profile object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe Profile object.
|
|
*/
|
|
export const createMockProfile = (overrides: Partial<Profile> = {}): Profile => {
|
|
const userId = overrides.user_id ?? `user-${Math.random().toString(36).substring(2, 9)}`;
|
|
|
|
const defaultProfile: Profile = {
|
|
user_id: userId,
|
|
updated_at: new Date().toISOString(),
|
|
full_name: 'Mock Profile User',
|
|
avatar_url: null,
|
|
address_id: null,
|
|
points: 0,
|
|
role: 'user',
|
|
preferences: {},
|
|
};
|
|
|
|
return { ...defaultProfile, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock WatchedItemDeal object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe WatchedItemDeal object.
|
|
*/
|
|
export const createMockWatchedItemDeal = (overrides: Partial<WatchedItemDeal> = {}): WatchedItemDeal => {
|
|
const defaultDeal: WatchedItemDeal = {
|
|
master_item_id: Math.floor(Math.random() * 1000),
|
|
item_name: 'Mock Deal Item',
|
|
best_price_in_cents: Math.floor(Math.random() * 1000) + 100,
|
|
store_name: 'Mock Store',
|
|
flyer_id: Math.floor(Math.random() * 100),
|
|
valid_to: new Date(Date.now() + 5 * 24 * 60 * 60 * 1000).toISOString(), // 5 days from now
|
|
};
|
|
|
|
return { ...defaultDeal, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock LeaderboardUser object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe LeaderboardUser object.
|
|
*/
|
|
export const createMockLeaderboardUser = (overrides: Partial<LeaderboardUser> = {}): LeaderboardUser => {
|
|
const userId = overrides.user_id ?? `user-${Math.random().toString(36).substring(2, 9)}`;
|
|
|
|
const defaultUser: LeaderboardUser = {
|
|
user_id: userId,
|
|
full_name: 'Leaderboard User',
|
|
avatar_url: null,
|
|
points: Math.floor(Math.random() * 1000),
|
|
rank: String(Math.floor(Math.random() * 100) + 1),
|
|
};
|
|
|
|
return { ...defaultUser, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock UnmatchedFlyerItem object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe UnmatchedFlyerItem object.
|
|
*/
|
|
export const createMockUnmatchedFlyerItem = (overrides: Partial<UnmatchedFlyerItem> = {}): UnmatchedFlyerItem => {
|
|
const defaultItem: UnmatchedFlyerItem = {
|
|
unmatched_flyer_item_id: Math.floor(Math.random() * 1000),
|
|
status: 'pending',
|
|
created_at: new Date().toISOString(),
|
|
flyer_item_id: Math.floor(Math.random() * 10000),
|
|
flyer_item_name: 'Mystery Product',
|
|
price_display: '$?.??',
|
|
flyer_id: Math.floor(Math.random() * 100),
|
|
store_name: 'Random Store',
|
|
};
|
|
|
|
return { ...defaultItem, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock AdminUserView object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe AdminUserView object.
|
|
*/
|
|
export const createMockAdminUserView = (overrides: Partial<AdminUserView> = {}): AdminUserView => {
|
|
const userId = overrides.user_id ?? `user-${Math.random().toString(36).substring(2, 9)}`;
|
|
|
|
const defaultUserView: AdminUserView = {
|
|
user_id: userId,
|
|
email: `${userId}@example.com`,
|
|
created_at: new Date().toISOString(),
|
|
role: 'user',
|
|
full_name: 'Mock User',
|
|
avatar_url: null,
|
|
};
|
|
|
|
return { ...defaultUserView, ...overrides };
|
|
};
|
|
|
|
/**
|
|
* Creates a mock Notification object for use in tests.
|
|
* @param overrides - An object containing properties to override the default mock values.
|
|
* @returns A complete and type-safe Notification object.
|
|
*/
|
|
export const createMockNotification = (overrides: Partial<Notification> = {}): Notification => {
|
|
const defaultNotification: Notification = {
|
|
notification_id: Math.floor(Math.random() * 1000),
|
|
user_id: `user-${Math.random().toString(36).substring(2, 9)}`,
|
|
content: 'This is a mock notification.',
|
|
link_url: null,
|
|
is_read: false,
|
|
created_at: new Date().toISOString(),
|
|
};
|
|
|
|
return { ...defaultNotification, ...overrides };
|
|
};
|
|
|
|
export const createMockAppliance = (overrides: Partial<Appliance> = {}): Appliance => {
|
|
return {
|
|
appliance_id: 1,
|
|
name: 'Oven',
|
|
...overrides,
|
|
};
|
|
}; |