Files
focusflow_shared/test/focusflow_shared_test.dart
Oracle Public Cloud User 1363f7d12d Initial scaffold: FocusFlow shared Dart package
Models (Task, Streak, StreakEntry, Reward, User, TimeEstimate, CoworkingRoom, ApiResponse),
enums (EnergyLevel, TaskStatus, RewardType, RewardStyle),
constants (ApiConstants, ErrorCodes, AppLimits), validators, and generated .g.dart files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 15:50:26 +00:00

206 lines
6.4 KiB
Dart

import 'package:focusflow_shared/focusflow_shared.dart';
import 'package:test/test.dart';
void main() {
group('Task', () {
test('creates with required fields', () {
final task = Task(
id: 'task-1',
userId: 'user-1',
title: 'Test task',
createdAt: DateTime(2024, 1, 1),
);
expect(task.id, 'task-1');
expect(task.title, 'Test task');
expect(task.status, 'pending');
expect(task.priority, 0);
expect(task.energyLevel, 'medium');
expect(task.noveltyFactor, 1.0);
expect(task.timesPostponed, 0);
expect(task.tags, isEmpty);
expect(task.version, 1);
});
test('serializes to JSON and back', () {
final task = Task(
id: 'task-1',
userId: 'user-1',
title: 'Test task',
priority: 50,
tags: ['focus', 'work'],
createdAt: DateTime(2024, 1, 1),
);
final json = task.toJson();
final restored = Task.fromJson(json);
expect(restored.id, task.id);
expect(restored.title, task.title);
expect(restored.priority, task.priority);
expect(restored.tags, task.tags);
});
});
group('Streak', () {
test('creates with defaults', () {
final streak = Streak(
id: 's-1',
userId: 'user-1',
name: 'Morning routine',
createdAt: DateTime(2024, 1, 1),
);
expect(streak.streakType, 'daily');
expect(streak.currentCount, 0);
expect(streak.graceDays, 2);
expect(streak.isActive, true);
expect(streak.encouragementShown, false);
});
test('serializes to JSON and back', () {
final streak = Streak(
id: 's-1',
userId: 'user-1',
name: 'Morning routine',
currentCount: 7,
longestCount: 14,
createdAt: DateTime(2024, 1, 1),
);
final json = streak.toJson();
final restored = Streak.fromJson(json);
expect(restored.name, streak.name);
expect(restored.currentCount, 7);
expect(restored.longestCount, 14);
});
});
group('User', () {
test('creates with defaults', () {
final user = User(
id: 'u-1',
email: 'test@example.com',
displayName: 'Test User',
createdAt: DateTime(2024, 1, 1),
);
expect(user.timezone, 'UTC');
expect(user.onboardingCompleted, false);
expect(user.preferredTaskLoad, 5);
expect(user.focusSessionMinutes, 25);
expect(user.rewardStyle, 'playful');
expect(user.forgivenessEnabled, true);
expect(user.subscriptionTier, 'free');
});
});
group('ApiResponse', () {
test('creates success response', () {
final response = ApiResponse<String>.success('hello');
expect(response.status, 'success');
expect(response.data, 'hello');
expect(response.error, isNull);
});
test('creates error response', () {
final response = ApiResponse<String>.error('NOT_FOUND', 'Task not found');
expect(response.status, 'error');
expect(response.data, isNull);
expect(response.error!.code, 'NOT_FOUND');
expect(response.error!.message, 'Task not found');
});
});
group('TaskValidator', () {
test('validates title - empty', () {
expect(TaskValidator.validateTitle(null), 'Title is required');
expect(TaskValidator.validateTitle(''), 'Title is required');
expect(TaskValidator.validateTitle(' '), 'Title is required');
});
test('validates title - too long', () {
final longTitle = 'x' * 501;
expect(TaskValidator.validateTitle(longTitle), 'Title must be 500 characters or less');
});
test('validates title - valid', () {
expect(TaskValidator.validateTitle('Buy groceries'), isNull);
});
test('validates estimated minutes', () {
expect(TaskValidator.validateEstimatedMinutes(null), isNull);
expect(TaskValidator.validateEstimatedMinutes(0), 'Estimate must be at least 1 minute');
expect(TaskValidator.validateEstimatedMinutes(481), 'Estimate cannot exceed 8 hours');
expect(TaskValidator.validateEstimatedMinutes(30), isNull);
});
test('validates priority', () {
expect(TaskValidator.validatePriority(null), isNull);
expect(TaskValidator.validatePriority(-1), 'Priority must be 0-100');
expect(TaskValidator.validatePriority(101), 'Priority must be 0-100');
expect(TaskValidator.validatePriority(50), isNull);
});
});
group('Enums', () {
test('TaskStatus display names', () {
expect(TaskStatus.pending.displayName, 'To Do');
expect(TaskStatus.inProgress.displayName, 'In Progress');
expect(TaskStatus.completed.displayName, 'Done');
});
test('TaskStatus API values', () {
expect(TaskStatus.pending.apiValue, 'pending');
expect(TaskStatus.inProgress.apiValue, 'in_progress');
});
test('EnergyLevel display names', () {
expect(EnergyLevel.low.displayName, 'Low Energy');
expect(EnergyLevel.medium.displayName, 'Medium Energy');
expect(EnergyLevel.high.displayName, 'High Energy');
});
test('RewardType display names', () {
expect(RewardType.animation.displayName, 'Celebration');
expect(RewardType.surprise.displayName, 'Surprise!');
});
test('RewardStyle display names', () {
expect(RewardStyle.playful.displayName, 'Playful (animations & messages)');
expect(RewardStyle.data.displayName, 'Data-driven (stats & charts)');
});
});
group('ApiConstants', () {
test('base path', () {
expect(ApiConstants.basePath, '/api/v1');
});
test('task routes', () {
expect(ApiConstants.tasks, '/api/v1/tasks');
expect(ApiConstants.task('abc'), '/api/v1/tasks/abc');
expect(ApiConstants.completeTask('abc'), '/api/v1/tasks/abc/complete');
});
test('room routes', () {
expect(ApiConstants.rooms, '/api/v1/rooms');
expect(ApiConstants.joinRoom('r1'), '/api/v1/rooms/r1/join');
});
});
group('AppLimits', () {
test('free tier limits', () {
expect(AppLimits.freeMaxActiveTasks, 15);
expect(AppLimits.freeMaxStreaks, 3);
});
test('pagination defaults', () {
expect(AppLimits.defaultPageSize, 20);
expect(AppLimits.maxPageSize, 100);
});
});
group('ErrorCodes', () {
test('error code values', () {
expect(ErrorCodes.taskNotFound, 'TASK_NOT_FOUND');
expect(ErrorCodes.premiumRequired, 'PREMIUM_REQUIRED');
expect(ErrorCodes.rateLimited, 'RATE_LIMITED');
});
});
}