mirror of
https://github.com/Dvorinka/1356.git
synced 2026-06-04 20:12:56 +00:00
feat: Complete Phase 1 - Full Flutter app implementation with comprehensive features
Version: 1.1.0 Major changes: - Implemented complete Flutter app structure with all core features - Added comprehensive UI screens for auth, countdown, goals, profile, settings, and social features - Integrated Supabase backend with authentication and data repositories - Added offline support with Hive caching and local storage - Implemented comprehensive routing with go_router - Added location services with Google Maps integration - Implemented notifications and home widget support - Added voice recording capabilities and AI chat features - Created comprehensive test suite and documentation - Added Android and iOS platform configurations - Implemented achievements system and social features - Added calendar integration and bucket list functionality This represents a complete Phase 1 milestone with 3,775 additions across 31 files.
This commit is contained in:
@@ -0,0 +1,341 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:lifetimer/data/models/user_model.dart';
|
||||
|
||||
void main() {
|
||||
group('User Model', () {
|
||||
group('Constructor and Properties', () {
|
||||
test('should create User with required fields', () {
|
||||
final user = User(
|
||||
id: 'user-1',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
createdAt: DateTime(2024, 1, 1),
|
||||
updatedAt: DateTime(2024, 1, 1),
|
||||
);
|
||||
|
||||
expect(user.id, equals('user-1'));
|
||||
expect(user.username, equals('testuser'));
|
||||
expect(user.email, equals('test@example.com'));
|
||||
expect(user.avatarUrl, isNull);
|
||||
expect(user.bio, isNull);
|
||||
expect(user.isPublicProfile, isFalse);
|
||||
expect(user.countdownStartDate, isNull);
|
||||
expect(user.countdownEndDate, isNull);
|
||||
});
|
||||
|
||||
test('should create User with all fields', () {
|
||||
final now = DateTime.now();
|
||||
final user = User(
|
||||
id: 'user-1',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
avatarUrl: 'https://example.com/avatar.jpg',
|
||||
bio: 'Test bio',
|
||||
isPublicProfile: true,
|
||||
countdownStartDate: now,
|
||||
countdownEndDate: now.add(const Duration(days: 1356)),
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
);
|
||||
|
||||
expect(user.id, equals('user-1'));
|
||||
expect(user.username, equals('testuser'));
|
||||
expect(user.email, equals('test@example.com'));
|
||||
expect(user.avatarUrl, equals('https://example.com/avatar.jpg'));
|
||||
expect(user.bio, equals('Test bio'));
|
||||
expect(user.isPublicProfile, isTrue);
|
||||
expect(user.countdownStartDate, equals(now));
|
||||
expect(user.countdownEndDate, equals(now.add(const Duration(days: 1356))));
|
||||
});
|
||||
});
|
||||
|
||||
group('Computed Properties', () {
|
||||
test('hasCountdownStarted should return false when countdownStartDate is null', () {
|
||||
final user = User(
|
||||
id: 'user-1',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
createdAt: DateTime.now(),
|
||||
updatedAt: DateTime.now(),
|
||||
);
|
||||
|
||||
expect(user.hasCountdownStarted, isFalse);
|
||||
});
|
||||
|
||||
test('hasCountdownStarted should return true when countdownStartDate is set', () {
|
||||
final user = User(
|
||||
id: 'user-1',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
countdownStartDate: DateTime.now(),
|
||||
createdAt: DateTime.now(),
|
||||
updatedAt: DateTime.now(),
|
||||
);
|
||||
|
||||
expect(user.hasCountdownStarted, isTrue);
|
||||
});
|
||||
|
||||
test('isCountdownActive should return false when countdown not started', () {
|
||||
final user = User(
|
||||
id: 'user-1',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
createdAt: DateTime.now(),
|
||||
updatedAt: DateTime.now(),
|
||||
);
|
||||
|
||||
expect(user.isCountdownActive, isFalse);
|
||||
});
|
||||
|
||||
test('isCountdownActive should return true when countdown is active', () {
|
||||
final user = User(
|
||||
id: 'user-1',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
countdownStartDate: DateTime.now().subtract(const Duration(days: 10)),
|
||||
countdownEndDate: DateTime.now().add(const Duration(days: 1346)),
|
||||
createdAt: DateTime.now(),
|
||||
updatedAt: DateTime.now(),
|
||||
);
|
||||
|
||||
expect(user.isCountdownActive, isTrue);
|
||||
});
|
||||
|
||||
test('isCountdownActive should return false when countdown has ended', () {
|
||||
final user = User(
|
||||
id: 'user-1',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
countdownStartDate: DateTime(2023, 1, 1),
|
||||
countdownEndDate: DateTime(2023, 12, 31),
|
||||
createdAt: DateTime(2023, 1, 1),
|
||||
updatedAt: DateTime(2023, 12, 31),
|
||||
);
|
||||
|
||||
expect(user.isCountdownActive, isFalse);
|
||||
});
|
||||
|
||||
test('daysRemaining should return null when countdown not active', () {
|
||||
final user = User(
|
||||
id: 'user-1',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
createdAt: DateTime.now(),
|
||||
updatedAt: DateTime.now(),
|
||||
);
|
||||
|
||||
expect(user.daysRemaining, isNull);
|
||||
});
|
||||
|
||||
test('daysRemaining should return correct days when countdown is active', () {
|
||||
final endDate = DateTime.now().add(const Duration(days: 100));
|
||||
final user = User(
|
||||
id: 'user-1',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
countdownStartDate: DateTime.now(),
|
||||
countdownEndDate: endDate,
|
||||
createdAt: DateTime.now(),
|
||||
updatedAt: DateTime.now(),
|
||||
);
|
||||
|
||||
final daysRemaining = user.daysRemaining;
|
||||
expect(daysRemaining, isNotNull);
|
||||
expect(daysRemaining, greaterThan(0));
|
||||
expect(daysRemaining, lessThanOrEqualTo(100));
|
||||
});
|
||||
});
|
||||
|
||||
group('copyWith', () {
|
||||
test('should create copy with updated fields', () {
|
||||
final user = User(
|
||||
id: 'user-1',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
createdAt: DateTime.now(),
|
||||
updatedAt: DateTime.now(),
|
||||
);
|
||||
|
||||
final updatedUser = user.copyWith(
|
||||
username: 'newuser',
|
||||
bio: 'New bio',
|
||||
);
|
||||
|
||||
expect(updatedUser.id, equals(user.id));
|
||||
expect(updatedUser.username, equals('newuser'));
|
||||
expect(updatedUser.email, equals(user.email));
|
||||
expect(updatedUser.bio, equals('New bio'));
|
||||
});
|
||||
|
||||
test('should preserve original when no fields provided', () {
|
||||
final user = User(
|
||||
id: 'user-1',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
createdAt: DateTime.now(),
|
||||
updatedAt: DateTime.now(),
|
||||
);
|
||||
|
||||
final copiedUser = user.copyWith();
|
||||
|
||||
expect(copiedUser.id, equals(user.id));
|
||||
expect(copiedUser.username, equals(user.username));
|
||||
expect(copiedUser.email, equals(user.email));
|
||||
});
|
||||
});
|
||||
|
||||
group('toJson and fromJson', () {
|
||||
test('should serialize to JSON correctly', () {
|
||||
final now = DateTime(2024, 1, 1, 12, 0, 0);
|
||||
final user = User(
|
||||
id: 'user-1',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
avatarUrl: 'https://example.com/avatar.jpg',
|
||||
bio: 'Test bio',
|
||||
isPublicProfile: true,
|
||||
countdownStartDate: now,
|
||||
countdownEndDate: now.add(const Duration(days: 1356)),
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
);
|
||||
|
||||
final json = user.toJson();
|
||||
|
||||
expect(json['id'], equals('user-1'));
|
||||
expect(json['username'], equals('testuser'));
|
||||
expect(json['email'], equals('test@example.com'));
|
||||
expect(json['avatar_url'], equals('https://example.com/avatar.jpg'));
|
||||
expect(json['bio'], equals('Test bio'));
|
||||
expect(json['is_public_profile'], isTrue);
|
||||
expect(json['countdown_start_date'], equals(now.toIso8601String()));
|
||||
expect(json['countdown_end_date'], equals(now.add(const Duration(days: 1356)).toIso8601String()));
|
||||
expect(json['created_at'], equals(now.toIso8601String()));
|
||||
expect(json['updated_at'], equals(now.toIso8601String()));
|
||||
});
|
||||
|
||||
test('should deserialize from JSON correctly', () {
|
||||
final now = DateTime(2024, 1, 1, 12, 0, 0);
|
||||
final json = {
|
||||
'id': 'user-1',
|
||||
'username': 'testuser',
|
||||
'email': 'test@example.com',
|
||||
'avatar_url': 'https://example.com/avatar.jpg',
|
||||
'bio': 'Test bio',
|
||||
'is_public_profile': true,
|
||||
'countdown_start_date': now.toIso8601String(),
|
||||
'countdown_end_date': now.add(const Duration(days: 1356)).toIso8601String(),
|
||||
'created_at': now.toIso8601String(),
|
||||
'updated_at': now.toIso8601String(),
|
||||
};
|
||||
|
||||
final user = User.fromJson(json);
|
||||
|
||||
expect(user.id, equals('user-1'));
|
||||
expect(user.username, equals('testuser'));
|
||||
expect(user.email, equals('test@example.com'));
|
||||
expect(user.avatarUrl, equals('https://example.com/avatar.jpg'));
|
||||
expect(user.bio, equals('Test bio'));
|
||||
expect(user.isPublicProfile, isTrue);
|
||||
expect(user.countdownStartDate, equals(now));
|
||||
expect(user.countdownEndDate, equals(now.add(const Duration(days: 1356))));
|
||||
});
|
||||
|
||||
test('should handle null optional fields in JSON', () {
|
||||
final now = DateTime(2024, 1, 1);
|
||||
final json = {
|
||||
'id': 'user-1',
|
||||
'username': 'testuser',
|
||||
'email': 'test@example.com',
|
||||
'avatar_url': null,
|
||||
'bio': null,
|
||||
'is_public_profile': null,
|
||||
'countdown_start_date': null,
|
||||
'countdown_end_date': null,
|
||||
'created_at': now.toIso8601String(),
|
||||
'updated_at': now.toIso8601String(),
|
||||
};
|
||||
|
||||
final user = User.fromJson(json);
|
||||
|
||||
expect(user.avatarUrl, isNull);
|
||||
expect(user.bio, isNull);
|
||||
expect(user.isPublicProfile, isFalse);
|
||||
expect(user.countdownStartDate, isNull);
|
||||
expect(user.countdownEndDate, isNull);
|
||||
});
|
||||
|
||||
test('should roundtrip through JSON', () {
|
||||
final user = User(
|
||||
id: 'user-1',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
avatarUrl: 'https://example.com/avatar.jpg',
|
||||
bio: 'Test bio',
|
||||
isPublicProfile: true,
|
||||
countdownStartDate: DateTime(2024, 1, 1),
|
||||
countdownEndDate: DateTime(2024, 1, 1).add(const Duration(days: 1356)),
|
||||
createdAt: DateTime(2024, 1, 1),
|
||||
updatedAt: DateTime(2024, 1, 1),
|
||||
);
|
||||
|
||||
final json = user.toJson();
|
||||
final deserializedUser = User.fromJson(json);
|
||||
|
||||
expect(deserializedUser.id, equals(user.id));
|
||||
expect(deserializedUser.username, equals(user.username));
|
||||
expect(deserializedUser.email, equals(user.email));
|
||||
expect(deserializedUser.avatarUrl, equals(user.avatarUrl));
|
||||
expect(deserializedUser.bio, equals(user.bio));
|
||||
expect(deserializedUser.isPublicProfile, equals(user.isPublicProfile));
|
||||
expect(deserializedUser.countdownStartDate, equals(user.countdownStartDate));
|
||||
expect(deserializedUser.countdownEndDate, equals(user.countdownEndDate));
|
||||
});
|
||||
});
|
||||
|
||||
group('Equatable', () {
|
||||
test('should be equal when all properties match', () {
|
||||
final now = DateTime.now();
|
||||
final user1 = User(
|
||||
id: 'user-1',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
);
|
||||
|
||||
final user2 = User(
|
||||
id: 'user-1',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
);
|
||||
|
||||
expect(user1, equals(user2));
|
||||
expect(user1.hashCode, equals(user2.hashCode));
|
||||
});
|
||||
|
||||
test('should not be equal when properties differ', () {
|
||||
final now = DateTime.now();
|
||||
final user1 = User(
|
||||
id: 'user-1',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
);
|
||||
|
||||
final user2 = User(
|
||||
id: 'user-2',
|
||||
username: 'testuser',
|
||||
email: 'test@example.com',
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
);
|
||||
|
||||
expect(user1, isNot(equals(user2)));
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user