// // JXDataModelTests.m // AICityTests // // Feature: 010-ui-ios // 数据模型单元测试 - Phase 1数据模型 // #import #import "JXDramaContent.h" #import "JXCommentContent.h" #import "JXEpisodeInfo.h" @interface JXDataModelTests : XCTestCase @end @implementation JXDataModelTests #pragma mark - JXDramaContent 测试 - (void)testJXDramaContentInitialization { // Given NSDictionary *dict = @{ @"drama_id": @"D001", @"title": @"测试短剧", @"cover": @"https://example.com/cover.jpg", @"description": @"这是一部测试短剧", @"total_episodes": @10, @"category_id": @1, @"tags": @[@"爱情", @"都市"], @"release_date": @"2025-01-01", @"rating": @4.5, @"play_count": @100000, @"like_count": @5000, @"favorite_count": @2000, @"comment_count": @800, @"is_vip": @YES, @"file_id": @"FILE123", @"app_id": @"APP456", @"psign": @"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBJZCI6MTI1Mn0.test" }; // When JXDramaContent *drama = [[JXDramaContent alloc] initWithDictionary:dict]; // Then XCTAssertNotNil(drama); XCTAssertEqualObjects(drama.dramaId, @"D001"); XCTAssertEqualObjects(drama.title, @"测试短剧"); XCTAssertEqualObjects(drama.cover, @"https://example.com/cover.jpg"); XCTAssertEqualObjects(drama.dramaDescription, @"这是一部测试短剧"); XCTAssertEqual(drama.totalEpisodes, 10); XCTAssertEqual(drama.categoryId, 1); XCTAssertEqual(drama.tags.count, 2); XCTAssertEqual(drama.rating, 4.5); XCTAssertEqual(drama.playCount, 100000); XCTAssertEqual(drama.likeCount, 5000); XCTAssertEqual(drama.favoriteCount, 2000); XCTAssertEqual(drama.commentCount, 800); XCTAssertTrue(drama.isVIP); XCTAssertEqualObjects(drama.fileId, @"FILE123"); XCTAssertEqualObjects(drama.appId, @"APP456"); XCTAssertEqualObjects(drama.psign, @"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBJZCI6MTI1Mn0.test"); } - (void)testJXDramaContentDefaultValues { // Given - 最小化字典 NSDictionary *dict = @{ @"drama_id": @"D002", @"title": @"简单短剧" }; // When JXDramaContent *drama = [[JXDramaContent alloc] initWithDictionary:dict]; // Then XCTAssertNotNil(drama); XCTAssertEqualObjects(drama.dramaId, @"D002"); XCTAssertEqualObjects(drama.title, @"简单短剧"); XCTAssertNil(drama.cover); XCTAssertNil(drama.dramaDescription); XCTAssertEqual(drama.totalEpisodes, 0); XCTAssertEqual(drama.playCount, 0); XCTAssertEqual(drama.likeCount, 0); XCTAssertFalse(drama.isVIP); } - (void)testJXDramaContentFormattedCounts { // Given NSDictionary *dict = @{ @"drama_id": @"D003", @"title": @"热门短剧", @"play_count": @123456789, @"like_count": @5678, @"favorite_count": @12345, @"comment_count": @890 }; // When JXDramaContent *drama = [[JXDramaContent alloc] initWithDictionary:dict]; // Then NSString *playCount = [drama formattedPlayCount]; NSString *likeCount = [drama formattedLikeCount]; NSString *favoriteCount = [drama formattedFavoriteCount]; NSString *commentCount = [drama formattedCommentCount]; XCTAssertNotNil(playCount); XCTAssertNotNil(likeCount); XCTAssertNotNil(favoriteCount); XCTAssertNotNil(commentCount); NSLog(@"播放量: %@", playCount); NSLog(@"点赞数: %@", likeCount); NSLog(@"收藏数: %@", favoriteCount); NSLog(@"评论数: %@", commentCount); } - (void)testJXDramaContentIsLikedAndFavorited { // Given NSDictionary *dict = @{ @"drama_id": @"D004", @"title": @"已点赞收藏", @"is_liked": @YES, @"is_favorited": @YES }; // When JXDramaContent *drama = [[JXDramaContent alloc] initWithDictionary:dict]; // Then XCTAssertTrue(drama.isLiked); XCTAssertTrue(drama.isFavorited); } #pragma mark - JXCommentContent 测试 - (void)testJXCommentContentInitialization { // Given NSDictionary *dict = @{ @"comment_id": @123456, @"user_id": @789, @"user_name": @"测试用户", @"user_avatar": @"https://example.com/avatar.jpg", @"content": @"这部剧太好看了!", @"like_count": @50, @"reply_count": @10, @"created_at": @1698000000000LL, // 毫秒时间戳 @"is_liked": @YES, @"is_author": @NO }; // When JXCommentContent *comment = [[JXCommentContent alloc] initWithDictionary:dict]; // Then XCTAssertNotNil(comment); XCTAssertEqual(comment.commentId, 123456); XCTAssertEqual(comment.userId, 789); XCTAssertEqualObjects(comment.userName, @"测试用户"); XCTAssertEqualObjects(comment.userAvatar, @"https://example.com/avatar.jpg"); XCTAssertEqualObjects(comment.content, @"这部剧太好看了!"); XCTAssertEqual(comment.likeCount, 50); XCTAssertEqual(comment.replyCount, 10); XCTAssertEqual(comment.createdAt, 1698000000000LL); XCTAssertTrue(comment.isLiked); XCTAssertFalse(comment.isAuthor); } - (void)testJXCommentContentFormattedTime { // Given - 今年内的评论 NSDate *now = [NSDate date]; NSCalendar *calendar = [NSCalendar currentCalendar]; NSInteger currentYear = [calendar component:NSCalendarUnitYear fromDate:now]; NSDateComponents *components = [[NSDateComponents alloc] init]; components.year = currentYear; components.month = 6; components.day = 15; NSDate *thisYear = [calendar dateFromComponents:components]; int64_t thisYearTimestamp = (int64_t)([thisYear timeIntervalSince1970] * 1000); NSDictionary *dict1 = @{ @"comment_id": @1, @"content": @"今年的评论", @"created_at": @(thisYearTimestamp) }; // Given - 非今年的评论 components.year = currentYear - 1; NSDate *lastYear = [calendar dateFromComponents:components]; int64_t lastYearTimestamp = (int64_t)([lastYear timeIntervalSince1970] * 1000); NSDictionary *dict2 = @{ @"comment_id": @2, @"content": @"去年的评论", @"created_at": @(lastYearTimestamp) }; // When JXCommentContent *comment1 = [[JXCommentContent alloc] initWithDictionary:dict1]; JXCommentContent *comment2 = [[JXCommentContent alloc] initWithDictionary:dict2]; // Then NSString *time1 = [comment1 formattedTime]; NSString *time2 = [comment2 formattedTime]; XCTAssertNotNil(time1); XCTAssertNotNil(time2); // 今年的应该是 MM-dd 格式 XCTAssertTrue([time1 rangeOfString:@"-"].location != NSNotFound); XCTAssertFalse([time1 hasPrefix:[NSString stringWithFormat:@"%ld", (long)currentYear]]); // 去年的应该是 yyyy-MM-dd 格式 XCTAssertTrue([time2 hasPrefix:[NSString stringWithFormat:@"%ld", (long)(currentYear - 1)]]); NSLog(@"今年评论时间: %@", time1); NSLog(@"去年评论时间: %@", time2); } - (void)testJXCommentContentFormattedCounts { // Given NSDictionary *dict = @{ @"comment_id": @1, @"content": @"热门评论", @"like_count": @12345, @"reply_count": @678 }; // When JXCommentContent *comment = [[JXCommentContent alloc] initWithDictionary:dict]; // Then NSString *likeCount = [comment formattedLikeCount]; NSString *replyCount = [comment formattedReplyCount]; XCTAssertNotNil(likeCount); XCTAssertNotNil(replyCount); NSLog(@"点赞数: %@", likeCount); NSLog(@"回复数: %@", replyCount); } #pragma mark - JXEpisodeInfo 测试 - (void)testJXEpisodeInfoInitialization { // Given NSDictionary *dict = @{ @"episode_id": @"EP001", @"episode_number": @5, @"title": @"第5集", @"cover": @"https://example.com/ep5.jpg", @"duration": @600, @"is_vip": @YES, @"file_id": @"FILE789", @"app_id": @"APP101", @"psign": @"test_psign" }; // When JXEpisodeInfo *episode = [[JXEpisodeInfo alloc] initWithDictionary:dict]; // Then XCTAssertNotNil(episode); XCTAssertEqualObjects(episode.episodeId, @"EP001"); XCTAssertEqual(episode.episodeNumber, 5); XCTAssertEqualObjects(episode.title, @"第5集"); XCTAssertEqualObjects(episode.cover, @"https://example.com/ep5.jpg"); XCTAssertEqual(episode.duration, 600); XCTAssertTrue(episode.isVIP); XCTAssertEqualObjects(episode.fileId, @"FILE789"); XCTAssertEqualObjects(episode.appId, @"APP101"); XCTAssertEqualObjects(episode.psign, @"test_psign"); } - (void)testJXEpisodeInfoFormattedDuration { // Given NSDictionary *dict1 = @{ @"episode_id": @"EP001", @"duration": @65 // 1分05秒 }; NSDictionary *dict2 = @{ @"episode_id": @"EP002", @"duration": @3665 // 1小时1分05秒 }; NSDictionary *dict3 = @{ @"episode_id": @"EP003", @"duration": @600 // 10分钟 }; // When JXEpisodeInfo *episode1 = [[JXEpisodeInfo alloc] initWithDictionary:dict1]; JXEpisodeInfo *episode2 = [[JXEpisodeInfo alloc] initWithDictionary:dict2]; JXEpisodeInfo *episode3 = [[JXEpisodeInfo alloc] initWithDictionary:dict3]; // Then NSString *duration1 = [episode1 formattedDuration]; NSString *duration2 = [episode2 formattedDuration]; NSString *duration3 = [episode3 formattedDuration]; XCTAssertEqualObjects(duration1, @"01:05"); XCTAssertEqualObjects(duration2, @"61:05"); XCTAssertEqualObjects(duration3, @"10:00"); NSLog(@"时长1: %@", duration1); NSLog(@"时长2: %@", duration2); NSLog(@"时长3: %@", duration3); } #pragma mark - 边界值测试 - (void)testNilDictionaryHandling { // When JXDramaContent *drama = [[JXDramaContent alloc] initWithDictionary:nil]; JXCommentContent *comment = [[JXCommentContent alloc] initWithDictionary:nil]; JXEpisodeInfo *episode = [[JXEpisodeInfo alloc] initWithDictionary:nil]; // Then - 应该优雅处理nil,不崩溃 XCTAssertNotNil(drama); XCTAssertNotNil(comment); XCTAssertNotNil(episode); } - (void)testEmptyDictionaryHandling { // When JXDramaContent *drama = [[JXDramaContent alloc] initWithDictionary:@{}]; JXCommentContent *comment = [[JXCommentContent alloc] initWithDictionary:@{}]; JXEpisodeInfo *episode = [[JXEpisodeInfo alloc] initWithDictionary:@{}]; // Then - 应该优雅处理空字典 XCTAssertNotNil(drama); XCTAssertNotNil(comment); XCTAssertNotNil(episode); } - (void)testInvalidDataTypeHandling { // Given - 错误的数据类型 NSDictionary *dict = @{ @"drama_id": @123, // 应该是字符串 @"title": @456, // 应该是字符串 @"total_episodes": @"abc", // 应该是数字 @"is_vip": @"yes" // 应该是布尔值 }; // When JXDramaContent *drama = [[JXDramaContent alloc] initWithDictionary:dict]; // Then - 应该优雅处理类型转换 XCTAssertNotNil(drama); } #pragma mark - 性能测试 - (void)testPerformanceJXDramaContentInitialization { NSDictionary *dict = @{ @"drama_id": @"D999", @"title": @"性能测试短剧", @"play_count": @100000, @"like_count": @5000 }; [self measureBlock:^{ for (int i = 0; i < 1000; i++) { JXDramaContent *drama = [[JXDramaContent alloc] initWithDictionary:dict]; (void)drama; } }]; } - (void)testPerformanceJXCommentContentInitialization { NSDictionary *dict = @{ @"comment_id": @123, @"content": @"性能测试评论", @"created_at": @1698000000000LL }; [self measureBlock:^{ for (int i = 0; i < 1000; i++) { JXCommentContent *comment = [[JXCommentContent alloc] initWithDictionary:dict]; (void)comment; } }]; } @end