GMPhotoTest.m 14.8 KB
//
//  GMPhotoTest.m
//  GMPhobos
//
//  Created by Thierry on 16/1/28.
//  Copyright © 2016年 licong. All rights reserved.
//

#import <XCTest/XCTest.h>
#import <GMPhobos/Phobos.h>
#import "GMPhobosController.h"
#define PhobosCacheKey        @"PhobosCacheKey"
@import GMCache;

NSString      *const MockAppName      = @"gengmei_test";
NSString      *const MockChannelId    = @"AppStore";
NSString      *const MockEventId      = @"eventId";
NSString      *const MockUserId       = @"1";
NSString      *const MockCityId       = @"beijing";

@interface GMPhotoTest : XCTestCase
@property Phobos *client;
@end

@implementation GMPhotoTest

- (void)setUp {
    [super setUp];
    _client = [Phobos clientWithAppName:MockAppName channelId:MockChannelId];
    _client.serverAPI = @"http://log.test.igengmei.com/log/collect";
    [_client setLogEnabled:NO]; // 调试打Log模式,看情况开启
    _client.signingType = PhobosSigningTypeDebug;
    _client.userId = @"";
    [Phobos setSharedClient:_client];
}

- (void)tearDown {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
    [super tearDown];
    [GMCache removeObjectAtDocumentPathWithkey:PhobosCacheKey];
    [GMCache removeObjectAtDocumentPathWithkey:PhobosTempCacheKey];
}

/**
 *  @brief 测试有用户ID的时候,埋点事件是否正确
 *
 *  @since <#version number#>
 */
- (void)testClientWithUserId{
    [_client setUserId:MockUserId];
    [_client setCurrentCityId:MockCityId];
    [Phobos track:MockEventId];
    NSArray *array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 1, @"array is empty");
    NSDictionary *dict = [array objectAtIndex:0];
    [self verfiyDict:dict];
    XCTAssertTrue([[dict objectForKey:@"user_id"] isEqualToString:MockUserId] , @"Invalid user_id value");
}

/**
 *  @brief 测试发送不带参数事件成功 (由之前的实例方法变成类方法)
 *
 *  @since <#version number#>
 */
- (void)testTrackEventWithoutAttr{
    [Phobos track:MockEventId];
    NSArray *array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 1, @"array is empty");
    NSDictionary *dict = [array objectAtIndex:0];
    [self verfiyDict:dict];
}


/**
 *  @brief 测试发送带参数事件成功
 *
 *  @since <#version number#>
 */
- (void)testTrackEventWithAttr{
    NSDictionary *attr = @{@"attr":@"track_attr"};
    [Phobos track:MockEventId attributes:attr];
    NSArray *array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 1, @"array is empty");
    NSDictionary *dict = [array objectAtIndex:0];
    [self verfiyDict:dict];
    
    //验证Param的值是否正确
    NSString *value = [[dict valueForKey:@"params"] valueForKey:@"attr"];
    XCTAssertTrue([value isEqualToString:@"track_attr"], @"Invalid event attributes");
}

/**
 *  @brief 测试立即发送带参数事件成功
 *
 *  @since <#version number#>
 */
- (void)testTrackEventWithAttrAndSendNow{
    // Given
    NSDictionary *attr = @{@"attr":@"track_attr"};
    // When
    [Phobos track:MockEventId attributes:attr sendNow:YES];
    // Then
    NSArray *array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 0, @"array should be empty");
}

/**
 *  @brief 测试立即发送带参数事件成功,不应该清除不立即发送的埋点
 *
 *  @since 1.1.4
 */
- (void)testTrackEventWithAttrAndSendNowDonotClearNormal {
    // Given
    NSDictionary *attr = @{@"attr":@"track_attr"};
    NSDictionary *sendNowAttr = @{@"attr":@"track_attr_send_now"};
    // When
    [Phobos track:MockEventId attributes:attr sendNow:NO];
    // When
    [Phobos track:MockEventId attributes:sendNowAttr sendNow:YES];
    
    NSArray *array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count != 0, @"array shouldn't be empty");
}

/**
 *  @brief 测试二次立即发送带参数事件成功,不应该重复发送上一条
 *
 *  @since 1.1.4
 */
- (void)testTrackEventWithDoubleAttrAndSendNow {
    NSDictionary *attr = @{@"attr":@"track_attr"};
    [Phobos track:MockEventId attributes:attr sendNow:YES];
    
    // 因为实时埋点是异步删除,所以这个位置暂时延时取数据,待优化 TODO
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSArray *array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosTempCacheKey];
        XCTAssertTrue(array.count == 0, @"array shouldn't be empty");
        [Phobos track:MockEventId attributes:attr sendNow:YES];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSArray *array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosTempCacheKey];
            XCTAssertTrue(array.count == 0, @"array shouldn't be empty");
            [Phobos track:MockEventId attributes:attr sendNow:YES];
            
            array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
            XCTAssertTrue(array.count == 0, @"array shouldn't be empty");
        });
    });
}

/**
  *  @brief 测试不立即发送带参数事件成功后,数据会被清除
  *
  *  @since 1.1.4
  */
- (void)testTrackEventWithDoubleAttrAndNoSendNow {
    NSDictionary *attr = @{@"attr":@"track_attr"};
    //
    [Phobos track:MockEventId attributes:attr];
    
    NSArray *array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 1, @"array shouldn't be empty");

    // PhobosCacheKey超过50条数据会自动上报,模拟此情况
    for (int i = 0; i < 50; i++) {
        [Phobos track:MockEventId attributes:attr];
    }
    array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 0, @"array shouldn't be empty");
    [Phobos track:MockEventId attributes:attr];
    
    array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 1, @"array shouldn't be empty");
}

/**
 *  @brief 测试不实时和实时穿插 1
 *
 *  @since 1.1.4
 */
- (void)testTrackEventWithSendNowAndNoSendNowOne {
    NSDictionary *attr = @{@"attr":@"track_attr"};
    NSDictionary *sendNowAttr = @{@"attr":@"track_attr_send_now"};
    
    for (int i = 0; i < 30; i++) {
        [Phobos track:MockEventId attributes:attr];
    }
    NSArray *array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 30, @"array shouldn't be empty");
    
    // PhobosCacheKey超过50条数据会自动上报,模拟此情况
    [Phobos track:MockEventId attributes:sendNowAttr sendNow:YES];
    array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 30, @"array shouldn't be empty");
    
    
    [Phobos track:MockEventId attributes:sendNowAttr sendNow:YES];
    array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 30, @"array shouldn't be empty");
    
    
    [Phobos track:MockEventId attributes:sendNowAttr sendNow:YES];
    array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 30, @"array shouldn't be empty");
    
    
    [Phobos track:MockEventId attributes:attr];
    
    array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 31, @"array shouldn't be empty");
}

/**
 *  @brief 测试不实时和实时穿插 2
 *
 *  @since 1.1.4
 */
- (void)testTrackEventWithSendNowAndNoSendNowTwo {
    NSDictionary *attr = @{@"attr":@"track_attr"};
    NSDictionary *sendNowAttr = @{@"attr":@"track_attr_send_now"};
    
    [Phobos track:MockEventId attributes:sendNowAttr sendNow:YES];
    NSArray *array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 0, @"array shouldn't be empty");
    
    [Phobos track:MockEventId attributes:attr];
    array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 1, @"array shouldn't be empty");
    
    [Phobos track:MockEventId attributes:attr];
    
    [Phobos track:MockEventId attributes:sendNowAttr sendNow:YES];
    array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 2, @"array shouldn't be empty");
    
    
    [Phobos track:MockEventId attributes:sendNowAttr sendNow:YES];
    array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 2, @"array shouldn't be empty");
    
    
    [Phobos track:MockEventId attributes:attr];
    
    array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 3, @"array shouldn't be empty");
}

/**
 *  @brief 测试不实时和实时穿插 3
 *
 *  @since 1.1.4
 */
- (void)testTrackEventWithSendNowAndNoSendNowThree {
    NSDictionary *attr = @{@"attr":@"track_attr"};
    //
    [Phobos track:MockEventId attributes:attr];
    
    NSArray *array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 1, @"array shouldn't be empty");
    
    // PhobosCacheKey超过50条数据会自动上报,模拟此情况
    for (int i = 0; i < 50; i++) {
        [Phobos track:MockEventId attributes:attr];
    }
    array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 0, @"array shouldn't be empty");
    [Phobos track:MockEventId attributes:attr];
    
    array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 1, @"array shouldn't be empty");
}

- (void)verfiyDict:(NSDictionary *)dict{
    NSArray *keys = [dict allKeys];
    XCTAssertTrue([keys containsObject:@"type"], @"Missing type");
    XCTAssertTrue([keys containsObject:@"app"], @"Missing app");
    XCTAssertTrue([keys containsObject:@"version"], @"Missing version");
    XCTAssertTrue([keys containsObject:@"device"], @"Missing device");
    XCTAssertTrue([keys containsObject:@"user_id"], @"Missing user_id");
    XCTAssertTrue([keys containsObject:@"create_at"], @"Missing create_at");
    XCTAssertTrue([keys containsObject:@"params"], @"Missing params");
}

- (void)testCatchNullInAttributes {
    _client.captureNullExpection = ^(NSString *eventId, NSDictionary *att) {
        NSCAssert([att[@"bussness_id"] integerValue] == 1244, @"testCatchNullInAttributes 没有捕获到有用信息");
    };
    NSDictionary *attributes = @{@"key": [NSNull null],
                                 @"bussness_id": @1244};
    [Phobos track:@"testCatchNullInAttributes" attributes:attributes];
}

// 某种情况下没有先走 onPageStart,只走了OnPageEnd,此时数据应该完整,某个key对应的value可以是空
- (void)testOnPageStart {
    GMPhobosController *controller = [GMPhobosController new];
    controller.pageName = @"pageNameTest";
    controller.businessId = @"businessIdTest";
    controller.referrerId = @"rreferrerIdTest";
    [controller viewWillAppear:true];

    XCTAssertTrue(controller.inTime.integerValue > 0, "inTime 应该有值");
}

// 某种情况下没有先走 onPageStart,只走了OnPageEnd,此时数据应该完整,某个key对应的value可以是空
- (void)testOnPageEnd {
    GMPhobosController *controller = [GMPhobosController new];
    controller.pageName = @"pageNameTest";
    controller.businessId = @"businessIdTest";
    controller.referrerId = @"rreferrerIdTest";
    [controller viewWillAppear:true];
    [controller viewWillDisappear:true];
    [self paramUnNilCheck];
    NSArray *array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count != 0, @"PhobosCacheKey 下面应该有数据");

    NSDictionary *dic = array[0][@"params"];
    XCTAssertTrue([dic[@"referrer_id"] isEqualToString:@"rreferrerIdTest"], @"referrerId至少使用默认的空字符串");

}

- (void)testSimulativePageViewEvent {
    [_client simulativePV:nil businessId:nil referer:nil];
    [self paramUnNilCheck];
}

- (void)paramUnNilCheck {
    NSArray *array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count != 0, @"PhobosCacheKey 下面应该有数据");

    NSDictionary *dic = array[0][@"params"];
    XCTAssertTrue(dic[@"page_name"] != nil, @"page_name至少使用默认的空字符串");
    XCTAssertTrue([dic[@"referer"] integerValue] >= 0, @"referer至少使用默认的空字符串");
    XCTAssertTrue(dic[@"business_id"] != nil, @"business_id至少使用默认的空字符串");
}

#pragma mark - 属性test

- (void)testNeedLogPV {
    UIViewController *controller = [UIViewController new];
    XCTAssertTrue(controller.needLogPV, @"needLogPV应该默认为YES");
    controller.needLogPV = NO;
    XCTAssertFalse(controller.needLogPV, @"needLogPV赋值为NO时应该NO");
}

- (void)testCheckPVPhobos {
    [GMCache removeObjectAtDocumentPathWithkey:PhobosCacheKey];
    NSString *inDate = [PhobosUtil currentTime];
    
    [NSThread sleepForTimeInterval:1];//模拟浏览页面,让out和in时间相差1s
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
    [dict setObject:[PhobosUtil currentTime] forKey:@"out"];
    [dict setObject:inDate forKey:@"in"];
    [dict setObject:@"test" forKey:@"page_name"];
    [dict setObject:@"" forKey:@"business_id"];
    [dict setObject:@"" forKey:@"referrer"];
    [dict setObject:@(0) forKey:@"fake"];
    [dict setObject:@"" forKey:@"referrer_id"];
    [dict setObject:@"" forKey:@"extra_param"];
    [dict setObject:@"" forKey:@"referrer_tab_name"];
    [dict setObject:@(0) forKey:@"is_push"];
    [Phobos track:@"page_view" attributes:dict];
    NSArray *array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 1, @"PhobosCacheKey 下面应该有数据");
    
    [Phobos track:@"page_view" attributes:dict];
    array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 1, @"PhobosCacheKey 上条数据不应该发送");
    
    [NSThread sleepForTimeInterval:2];//模拟浏览页面,让第二次浏览和上一次时间相差2s
    
    [dict setObject:[PhobosUtil currentTime] forKey:@"in"];
    [NSThread sleepForTimeInterval:1];//模拟浏览页面,让out和in时间相差1s
    [dict setObject:[PhobosUtil currentTime] forKey:@"out"];
    [Phobos track:@"page_view" attributes:dict];
    array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 2, @"PhobosCacheKey 上条数据应该发送");
    [Phobos track:@"page_view" attributes:dict];
    array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 2, @"PhobosCacheKey 上条数据不应该发送");
    [Phobos track:@"test" attributes:dict];
    array = [GMCache fetchObjectAtDocumentPathWithkey:PhobosCacheKey];
    XCTAssertTrue(array.count == 3, @"PhobosCacheKey 上条数据应该发送");
}


#pragma mark - 其它方法test

- (void)testVisibleController {
    
}
@end