Add API contract Dart models
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:tdc114plus/src/core/network/api_error.dart';
|
||||
|
||||
void main() {
|
||||
test('ApiError parses common error payload', () {
|
||||
final error = ApiError.fromJson({
|
||||
'error': 'Unauthorized',
|
||||
'code': 'unauthorized',
|
||||
'details': {'reason': 'expired'},
|
||||
});
|
||||
|
||||
expect(error.code, 'unauthorized');
|
||||
expect(error.details['reason'], 'expired');
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:tdc114plus/src/features/auth/domain/auth_models.dart';
|
||||
|
||||
void main() {
|
||||
test('PhoneLoginRequest serializes phone login payload', () {
|
||||
const request = PhoneLoginRequest(
|
||||
phoneNumber: '01012345678',
|
||||
device: LoginDeviceInfo(
|
||||
platform: 'android',
|
||||
appVersion: '0.1.0',
|
||||
deviceName: 'Pixel 8',
|
||||
),
|
||||
);
|
||||
|
||||
expect(request.toJson(), {
|
||||
'phoneNumber': '01012345678',
|
||||
'device': {
|
||||
'platform': 'android',
|
||||
'appVersion': '0.1.0',
|
||||
'deviceName': 'Pixel 8',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('PhoneLoginResponse parses session token response', () {
|
||||
final response = PhoneLoginResponse.fromJson({
|
||||
'status': 'ok',
|
||||
'token': 'baron-sso-session-token',
|
||||
'expiresAt': '2026-07-02T12:00:00Z',
|
||||
'user': {
|
||||
'id': 'user-uuid',
|
||||
'name': 'User One',
|
||||
'phoneNumber': '+821012345678',
|
||||
'tenantId': 'tenant-uuid',
|
||||
'tenantName': 'Hanmac',
|
||||
'tenantSlug': 'hanmac',
|
||||
'department': 'Engineering',
|
||||
'grade': 'Lead',
|
||||
'position': 'Manager',
|
||||
'jobTitle': 'Developer',
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status, 'ok');
|
||||
expect(response.token, 'baron-sso-session-token');
|
||||
expect(
|
||||
response.expiresAt.toUtc().toIso8601String(),
|
||||
'2026-07-02T12:00:00.000Z',
|
||||
);
|
||||
expect(response.user.tenantSlug, 'hanmac');
|
||||
});
|
||||
|
||||
test('CurrentUser parses permissions and can map to employee', () {
|
||||
final user = CurrentUser.fromJson({
|
||||
'id': 'user-uuid',
|
||||
'name': 'User One',
|
||||
'phoneNumber': '+821012345678',
|
||||
'email': 'user@example.com',
|
||||
'tenantId': 'tenant-uuid',
|
||||
'tenantName': 'Hanmac',
|
||||
'tenantSlug': 'hanmac',
|
||||
'department': 'Engineering',
|
||||
'permissions': {
|
||||
'directory': true,
|
||||
'organization': true,
|
||||
'favoritesSync': false,
|
||||
},
|
||||
});
|
||||
|
||||
expect(user.permissions.directory, isTrue);
|
||||
expect(user.permissions.favoritesSync, isFalse);
|
||||
expect(user.toEmployee().department, 'Engineering');
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:tdc114plus/src/features/directory/domain/employee.dart';
|
||||
|
||||
void main() {
|
||||
test('EmployeeListResponse parses paginated employee list', () {
|
||||
final response = EmployeeListResponse.fromJson({
|
||||
'items': [
|
||||
{
|
||||
'id': 'user-uuid',
|
||||
'name': 'User One',
|
||||
'phoneNumber': '+821012345678',
|
||||
'phoneDisplay': '010-1234-5678',
|
||||
'email': 'user@example.com',
|
||||
'tenantId': 'tenant-uuid',
|
||||
'tenantName': 'Hanmac',
|
||||
'tenantSlug': 'hanmac',
|
||||
'department': 'Engineering',
|
||||
'grade': 'Lead',
|
||||
'position': 'Manager',
|
||||
'jobTitle': 'Developer',
|
||||
'status': 'active',
|
||||
'profileImageUrl': null,
|
||||
'sortOrder': 100,
|
||||
},
|
||||
],
|
||||
'limit': 50,
|
||||
'offset': 0,
|
||||
'total': 1,
|
||||
'nextCursor': '',
|
||||
});
|
||||
|
||||
expect(response.items, hasLength(1));
|
||||
expect(response.items.first.phoneDisplay, '010-1234-5678');
|
||||
expect(response.total, 1);
|
||||
});
|
||||
|
||||
test('EmployeeDetail parses joined tenants and available actions', () {
|
||||
final detail = EmployeeDetail.fromJson({
|
||||
'id': 'user-uuid',
|
||||
'name': 'User One',
|
||||
'phoneNumber': '+821012345678',
|
||||
'email': 'user@example.com',
|
||||
'tenantId': 'tenant-uuid',
|
||||
'tenantName': 'Hanmac',
|
||||
'tenantSlug': 'hanmac',
|
||||
'joinedTenants': [
|
||||
{
|
||||
'id': 'tenant-uuid',
|
||||
'name': 'Hanmac',
|
||||
'slug': 'hanmac',
|
||||
'type': 'COMPANY',
|
||||
'parentId': 'root-tenant-uuid',
|
||||
},
|
||||
],
|
||||
'status': 'active',
|
||||
'actions': {'call': true, 'sms': true, 'email': true},
|
||||
});
|
||||
|
||||
expect(detail.joinedTenants.first.type, 'COMPANY');
|
||||
expect(detail.actions.call, isTrue);
|
||||
expect(detail.actions.sms, isTrue);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:tdc114plus/src/features/organization/domain/organization_models.dart';
|
||||
|
||||
void main() {
|
||||
test('TenantListResponse parses organization filter tenants', () {
|
||||
final response = TenantListResponse.fromJson({
|
||||
'items': [
|
||||
{
|
||||
'id': 'tenant-uuid',
|
||||
'name': 'Hanmac',
|
||||
'slug': 'hanmac',
|
||||
'type': 'COMPANY',
|
||||
'parentId': 'family-root',
|
||||
'memberCount': 120,
|
||||
'totalMemberCount': 350,
|
||||
},
|
||||
],
|
||||
'generatedAt': '2026-07-02T12:00:00Z',
|
||||
});
|
||||
|
||||
expect(response.items.first.slug, 'hanmac');
|
||||
expect(response.items.first.totalMemberCount, 350);
|
||||
});
|
||||
|
||||
test('OrgChartSnapshot parses tenants, employees, and cache metadata', () {
|
||||
final snapshot = OrgChartSnapshot.fromJson({
|
||||
'tenants': [
|
||||
{
|
||||
'id': 'tenant-uuid',
|
||||
'name': 'Engineering',
|
||||
'slug': 'engineering',
|
||||
'type': 'ORGANIZATION',
|
||||
'parentId': 'company-tenant-uuid',
|
||||
'memberCount': 12,
|
||||
'totalMemberCount': 38,
|
||||
},
|
||||
],
|
||||
'employees': [
|
||||
{
|
||||
'id': 'user-uuid',
|
||||
'name': 'User One',
|
||||
'phoneNumber': '+821012345678',
|
||||
'phoneDisplay': '010-1234-5678',
|
||||
'tenantId': 'tenant-uuid',
|
||||
'tenantName': 'Engineering',
|
||||
'tenantSlug': 'engineering',
|
||||
'department': 'Engineering',
|
||||
'grade': 'Lead',
|
||||
'position': 'Manager',
|
||||
'jobTitle': 'Developer',
|
||||
'status': 'active',
|
||||
},
|
||||
],
|
||||
'generatedAt': '2026-07-02T12:00:00Z',
|
||||
'cache': {'source': 'redis', 'hit': true, 'ttlSeconds': 300},
|
||||
});
|
||||
|
||||
expect(snapshot.tenants.first.type, 'ORGANIZATION');
|
||||
expect(snapshot.employees.first.tenantSlug, 'engineering');
|
||||
expect(snapshot.cache?.source, 'redis');
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user