| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- //
- // JXPlaybackProgressStorageTests.m
- // AICityTests
- //
- // Feature: 003-ios-api-https
- // 播放进度本地存储单元测试
- //
- #import <XCTest/XCTest.h>
- #import "JXPlaybackProgressStorage.h"
- #import "JXPlaybackProgressModel.h"
- @interface JXPlaybackProgressStorageTests : XCTestCase
- @property (nonatomic, strong) JXPlaybackProgressStorage *storage;
- @end
- @implementation JXPlaybackProgressStorageTests
- - (void)setUp {
- [super setUp];
- self.storage = [JXPlaybackProgressStorage sharedStorage];
-
- // 清空所有数据
- [self.storage clearAll];
- }
- - (void)tearDown {
- // 清理测试数据
- [self.storage clearAll];
- [super tearDown];
- }
- #pragma mark - 基础功能测试
- - (void)testSaveAndGetProgress {
- // Given
- NSString *episodeId = @"test_ep_001";
- NSString *dramaId = @"test_drama_001";
- int64_t position = 30000;
- int64_t duration = 120000;
-
- // When
- XCTestExpectation *expectation = [self expectationWithDescription:@"Save progress"];
- [self.storage saveProgressWithEpisodeId:episodeId
- dramaId:dramaId
- position:position
- duration:duration
- isCompleted:NO
- synced:NO
- completion:^(BOOL success, NSError *error) {
- XCTAssertTrue(success, @"保存应该成功");
- XCTAssertNil(error, @"不应该有错误");
- [expectation fulfill];
- }];
-
- [self waitForExpectationsWithTimeout:5.0 handler:nil];
-
- // Then
- JXPlaybackProgressModel *progress = [self.storage getProgressWithEpisodeId:episodeId];
- XCTAssertNotNil(progress, @"应该能获取到进度");
- XCTAssertEqualObjects(progress.episodeId, episodeId);
- XCTAssertEqualObjects(progress.dramaId, dramaId);
- XCTAssertEqual(progress.position, position);
- XCTAssertEqual(progress.duration, duration);
- XCTAssertEqualWithAccuracy(progress.progress, 0.25f, 0.01f); // 30000/120000 = 0.25
- XCTAssertFalse(progress.isCompleted);
- XCTAssertFalse(progress.synced);
- }
- - (void)testUpdateExistingProgress {
- // Given
- NSString *episodeId = @"test_ep_002";
- XCTestExpectation *expectation1 = [self expectationWithDescription:@"Save initial"];
- [self.storage saveProgressWithEpisodeId:episodeId
- dramaId:@"test_drama_002"
- position:10000
- duration:120000
- isCompleted:NO
- synced:NO
- completion:^(BOOL success, NSError *error) {
- [expectation1 fulfill];
- }];
- [self waitForExpectationsWithTimeout:5.0 handler:nil];
-
- // When - 更新进度
- XCTestExpectation *expectation2 = [self expectationWithDescription:@"Update progress"];
- [self.storage saveProgressWithEpisodeId:episodeId
- dramaId:@"test_drama_002"
- position:60000
- duration:120000
- isCompleted:NO
- synced:YES
- completion:^(BOOL success, NSError *error) {
- [expectation2 fulfill];
- }];
- [self waitForExpectationsWithTimeout:5.0 handler:nil];
-
- // Then
- JXPlaybackProgressModel *progress = [self.storage getProgressWithEpisodeId:episodeId];
- XCTAssertEqual(progress.position, 60000);
- XCTAssertEqualWithAccuracy(progress.progress, 0.5f, 0.01f);
- XCTAssertTrue(progress.synced);
- }
- - (void)testGetProgressByDrama {
- // Given
- NSString *dramaId = @"test_drama_003";
- XCTestExpectation *expectation = [self expectationWithDescription:@"Save multiple"];
-
- [self.storage saveProgressWithEpisodeId:@"ep001" dramaId:dramaId position:10000 duration:120000 isCompleted:NO synced:NO completion:nil];
- [self.storage saveProgressWithEpisodeId:@"ep002" dramaId:dramaId position:20000 duration:120000 isCompleted:NO synced:NO completion:nil];
- [self.storage saveProgressWithEpisodeId:@"ep003" dramaId:@"other_drama" position:30000 duration:120000 isCompleted:NO synced:NO completion:^(BOOL success, NSError *error) {
- [expectation fulfill];
- }];
-
- [self waitForExpectationsWithTimeout:5.0 handler:nil];
-
- // When
- NSArray<JXPlaybackProgressModel *> *progresses = [self.storage getProgressByDramaId:dramaId];
-
- // Then
- XCTAssertEqual(progresses.count, 2, @"应该有2条记录");
- BOOL hasEp001 = NO;
- BOOL hasEp002 = NO;
- for (JXPlaybackProgressModel *p in progresses) {
- if ([p.episodeId isEqualToString:@"ep001"]) hasEp001 = YES;
- if ([p.episodeId isEqualToString:@"ep002"]) hasEp002 = YES;
- }
- XCTAssertTrue(hasEp001 && hasEp002, @"应该包含ep001和ep002");
- }
- - (void)testGetUnsyncedProgresses {
- // Given
- XCTestExpectation *expectation = [self expectationWithDescription:@"Save progresses"];
-
- [self.storage saveProgressWithEpisodeId:@"ep001" dramaId:@"drama" position:10000 duration:120000 isCompleted:NO synced:YES completion:nil];
- [self.storage saveProgressWithEpisodeId:@"ep002" dramaId:@"drama" position:20000 duration:120000 isCompleted:NO synced:NO completion:nil];
- [self.storage saveProgressWithEpisodeId:@"ep003" dramaId:@"drama" position:30000 duration:120000 isCompleted:NO synced:NO completion:^(BOOL success, NSError *error) {
- [expectation fulfill];
- }];
-
- [self waitForExpectationsWithTimeout:5.0 handler:nil];
-
- // When
- NSArray<JXPlaybackProgressModel *> *unsyncedProgresses = [self.storage getUnsyncedProgresses];
-
- // Then
- XCTAssertEqual(unsyncedProgresses.count, 2, @"应该有2条未同步记录");
- for (JXPlaybackProgressModel *p in unsyncedProgresses) {
- XCTAssertFalse(p.synced, @"所有记录都应该是未同步的");
- }
- }
- - (void)testMarkAsSynced {
- // Given
- NSString *episodeId = @"test_ep_004";
- XCTestExpectation *expectation = [self expectationWithDescription:@"Save progress"];
- [self.storage saveProgressWithEpisodeId:episodeId
- dramaId:@"drama"
- position:10000
- duration:120000
- isCompleted:NO
- synced:NO
- completion:^(BOOL success, NSError *error) {
- [expectation fulfill];
- }];
- [self waitForExpectationsWithTimeout:5.0 handler:nil];
-
- // When
- [self.storage markAsSyncedWithEpisodeId:episodeId];
-
- // Then
- JXPlaybackProgressModel *progress = [self.storage getProgressWithEpisodeId:episodeId];
- XCTAssertTrue(progress.synced, @"应该被标记为已同步");
- }
- - (void)testDeleteProgress {
- // Given
- NSString *episodeId = @"test_ep_005";
- XCTestExpectation *expectation = [self expectationWithDescription:@"Save progress"];
- [self.storage saveProgressWithEpisodeId:episodeId dramaId:@"drama" position:10000 duration:120000 isCompleted:NO synced:NO completion:^(BOOL success, NSError *error) {
- [expectation fulfill];
- }];
- [self waitForExpectationsWithTimeout:5.0 handler:nil];
-
- XCTAssertNotNil([self.storage getProgressWithEpisodeId:episodeId], @"保存后应该存在");
-
- // When
- [self.storage deleteProgressWithEpisodeId:episodeId];
-
- // Then
- JXPlaybackProgressModel *progress = [self.storage getProgressWithEpisodeId:episodeId];
- XCTAssertNil(progress, @"删除后应该不存在");
- }
- - (void)testDeleteProgressByDrama {
- // Given
- NSString *dramaId = @"test_drama_006";
- XCTestExpectation *expectation = [self expectationWithDescription:@"Save progresses"];
-
- [self.storage saveProgressWithEpisodeId:@"ep001" dramaId:dramaId position:10000 duration:120000 isCompleted:NO synced:NO completion:nil];
- [self.storage saveProgressWithEpisodeId:@"ep002" dramaId:dramaId position:20000 duration:120000 isCompleted:NO synced:NO completion:^(BOOL success, NSError *error) {
- [expectation fulfill];
- }];
-
- [self waitForExpectationsWithTimeout:5.0 handler:nil];
-
- // When
- [self.storage deleteProgressByDramaId:dramaId];
-
- // Then
- NSArray *progresses = [self.storage getProgressByDramaId:dramaId];
- XCTAssertEqual(progresses.count, 0, @"删除后应该没有记录");
- }
- #pragma mark - 边界值测试
- - (void)testProgressCalculation {
- XCTestExpectation *expectation = [self expectationWithDescription:@"Save progresses"];
-
- // Test case 1: 25% progress
- [self.storage saveProgressWithEpisodeId:@"ep_25" dramaId:@"drama" position:30000 duration:120000 isCompleted:NO synced:NO completion:nil];
-
- // Test case 2: 50% progress
- [self.storage saveProgressWithEpisodeId:@"ep_50" dramaId:@"drama" position:60000 duration:120000 isCompleted:NO synced:NO completion:nil];
-
- // Test case 3: 95% progress (completed)
- [self.storage saveProgressWithEpisodeId:@"ep_95" dramaId:@"drama" position:114000 duration:120000 isCompleted:YES synced:NO completion:^(BOOL success, NSError *error) {
- [expectation fulfill];
- }];
-
- [self waitForExpectationsWithTimeout:5.0 handler:nil];
-
- // Verify
- JXPlaybackProgressModel *progress25 = [self.storage getProgressWithEpisodeId:@"ep_25"];
- XCTAssertEqualWithAccuracy(progress25.progress, 0.25f, 0.01f);
-
- JXPlaybackProgressModel *progress50 = [self.storage getProgressWithEpisodeId:@"ep_50"];
- XCTAssertEqualWithAccuracy(progress50.progress, 0.5f, 0.01f);
-
- JXPlaybackProgressModel *progress95 = [self.storage getProgressWithEpisodeId:@"ep_95"];
- XCTAssertEqualWithAccuracy(progress95.progress, 0.95f, 0.01f);
- XCTAssertTrue(progress95.isCompleted);
- }
- - (void)testEdgeCases {
- XCTestExpectation *expectation = [self expectationWithDescription:@"Save edge cases"];
-
- // Test case 1: Zero duration
- [self.storage saveProgressWithEpisodeId:@"ep_zero" dramaId:@"drama" position:0 duration:0 isCompleted:NO synced:NO completion:nil];
-
- // Test case 2: Position exceeds duration
- [self.storage saveProgressWithEpisodeId:@"ep_exceed" dramaId:@"drama" position:150000 duration:120000 isCompleted:NO synced:NO completion:^(BOOL success, NSError *error) {
- [expectation fulfill];
- }];
-
- [self waitForExpectationsWithTimeout:5.0 handler:nil];
-
- // Verify
- JXPlaybackProgressModel *progressZero = [self.storage getProgressWithEpisodeId:@"ep_zero"];
- XCTAssertEqual(progressZero.progress, 0.0f);
-
- JXPlaybackProgressModel *progressExceed = [self.storage getProgressWithEpisodeId:@"ep_exceed"];
- XCTAssertLessThanOrEqual(progressExceed.progress, 1.0f);
- }
- #pragma mark - 性能测试
- - (void)testPerformanceSaveMultipleProgresses {
- [self measureBlock:^{
- for (int i = 0; i < 100; i++) {
- NSString *episodeId = [NSString stringWithFormat:@"perf_ep_%d", i];
- [self.storage saveProgressWithEpisodeId:episodeId
- dramaId:@"perf_drama"
- position:i * 1000
- duration:120000
- isCompleted:NO
- synced:NO
- completion:nil];
- }
- }];
- }
- - (void)testPerformanceQueryProgresses {
- // 准备数据
- for (int i = 0; i < 100; i++) {
- NSString *episodeId = [NSString stringWithFormat:@"query_ep_%d", i];
- [self.storage saveProgressWithEpisodeId:episodeId dramaId:@"query_drama" position:i * 1000 duration:120000 isCompleted:NO synced:NO completion:nil];
- }
-
- // 测试查询性能
- [self measureBlock:^{
- NSArray *progresses = [self.storage getProgressByDramaId:@"query_drama"];
- XCTAssertGreaterThan(progresses.count, 0);
- }];
- }
- @end
|