Add unit tests for clients, auth, and theme

This commit is contained in:
2026-01-27 18:30:06 +00:00
parent e39cb841ed
commit ce6e7598dd
3 changed files with 364 additions and 0 deletions

View File

@@ -0,0 +1,116 @@
import 'package:flutter_test/flutter_test.dart';
void main() {
group('Auth Validation', () {
test('email is required for login', () {
final email = '';
expect(email.isEmpty, isTrue);
});
test('password is required for login', () {
final password = '';
expect(password.isEmpty, isTrue);
});
test('valid email format', () {
final email = 'user@example.com';
final emailRegex = RegExp(r'^[^\s@]+@[^\s@]+\.[^\s@]+$');
expect(emailRegex.hasMatch(email), isTrue);
});
test('invalid email format rejected', () {
final invalidEmails = [
'notanemail',
'missing@',
'@nodomain.com',
];
final emailRegex = RegExp(r'^[^\s@]+@[^\s@]+\.[^\s@]+$');
for (final email in invalidEmails) {
expect(emailRegex.hasMatch(email), isFalse);
}
});
test('password minimum length', () {
final password = 'short';
final minLength = 8;
expect(password.length >= minLength, isFalse);
});
test('valid password length', () {
final password = 'securepassword123';
final minLength = 8;
expect(password.length >= minLength, isTrue);
});
});
group('Registration Validation', () {
test('name is required', () {
final name = '';
expect(name.isEmpty, isTrue);
});
test('name has minimum length', () {
final name = 'J';
final minLength = 2;
expect(name.length >= minLength, isFalse);
});
test('password confirmation must match', () {
final password = 'securepassword';
final confirmation = 'securepassword';
expect(password == confirmation, isTrue);
});
test('mismatched passwords detected', () {
final password = 'securepassword';
final confirmation = 'differentpassword';
expect(password == confirmation, isFalse);
});
});
group('Token Management', () {
test('token is stored after login', () {
final token = 'jwt_token_here';
expect(token.isNotEmpty, isTrue);
});
test('token format is valid', () {
// Simple check - real JWT has 3 parts separated by dots
final token = 'header.payload.signature';
final parts = token.split('.');
expect(parts.length, 3);
});
test('empty token is invalid', () {
final token = '';
expect(token.isEmpty, isTrue);
});
});
group('Auth State', () {
test('initial state is unauthenticated', () {
const isAuthenticated = false;
expect(isAuthenticated, isFalse);
});
test('state changes after login', () {
var isAuthenticated = false;
// Simulate login
isAuthenticated = true;
expect(isAuthenticated, isTrue);
});
test('state changes after logout', () {
var isAuthenticated = true;
// Simulate logout
isAuthenticated = false;
expect(isAuthenticated, isFalse);
});
});
}

View File

@@ -0,0 +1,159 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('Client Data', () {
test('client name combines first and last', () {
final client = {
'firstName': 'John',
'lastName': 'Doe',
};
final name = '${client['firstName']} ${client['lastName']}';
expect(name, 'John Doe');
});
test('client initials are extracted correctly', () {
final client = {
'firstName': 'John',
'lastName': 'Doe',
};
final initials = '${client['firstName']![0]}${client['lastName']![0]}';
expect(initials, 'JD');
});
test('tags default to empty list', () {
final client = <String, dynamic>{
'firstName': 'John',
'lastName': 'Doe',
'tags': null,
};
final tags = (client['tags'] as List?)?.cast<String>() ?? [];
expect(tags, isEmpty);
});
test('tags list contains expected items', () {
final client = {
'firstName': 'John',
'lastName': 'Doe',
'tags': ['vip', 'active'],
};
final tags = (client['tags'] as List?)?.cast<String>() ?? [];
expect(tags, hasLength(2));
expect(tags, contains('vip'));
});
test('company can be null', () {
final client = {
'firstName': 'John',
'lastName': 'Doe',
'company': null,
};
final company = client['company'] as String?;
expect(company, isNull);
});
test('company can be empty string', () {
final client = {
'firstName': 'John',
'lastName': 'Doe',
'company': '',
};
final company = client['company'] as String?;
final hasCompany = company != null && company.isNotEmpty;
expect(hasCompany, isFalse);
});
});
group('Search Functionality', () {
test('empty search returns null query', () {
final searchText = '';
final query = searchText.isEmpty ? null : searchText;
expect(query, isNull);
});
test('non-empty search returns query', () {
final searchText = 'John';
final query = searchText.isEmpty ? null : searchText;
expect(query, 'John');
});
test('whitespace-only considered non-empty', () {
final searchText = ' ';
final query = searchText.isEmpty ? null : searchText;
expect(query, isNotNull); // Note: might want to trim
});
});
group('Client List Display', () {
test('shows maximum 3 tags', () {
final tags = ['vip', 'active', 'referral', 'premium', 'gold'];
final displayTags = tags.take(3).toList();
expect(displayTags, hasLength(3));
expect(displayTags, ['vip', 'active', 'referral']);
});
test('empty list shows empty message', () {
final clients = <Map<String, dynamic>>[];
expect(clients.isEmpty, isTrue);
});
});
}
group('Client Form Validation', () {
test('first name is required', () {
final firstName = '';
final isValid = firstName.isNotEmpty;
expect(isValid, isFalse);
});
test('last name is required', () {
final lastName = '';
final isValid = lastName.isNotEmpty;
expect(isValid, isFalse);
});
test('email format validation', () {
final validEmails = [
'test@example.com',
'user.name@domain.org',
];
final emailRegex = RegExp(r'^[^\s@]+@[^\s@]+\.[^\s@]+$');
for (final email in validEmails) {
expect(emailRegex.hasMatch(email), isTrue);
}
});
test('invalid email detected', () {
final invalidEmails = [
'notanemail',
'@missing.local',
'missing@domain',
];
final emailRegex = RegExp(r'^[^\s@]+@[^\s@]+\.[^\s@]+$');
for (final email in invalidEmails) {
expect(emailRegex.hasMatch(email), isFalse);
}
});
test('phone number can have various formats', () {
final phones = [
'+1234567890',
'(123) 456-7890',
'123-456-7890',
];
for (final phone in phones) {
expect(phone.isNotEmpty, isTrue);
}
});
});