blob: dc5c49eb8dace8c51ce25624540dfbba1cd8cc5a [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ios/net/cookies/cookie_creation_time_manager.h"
#import <Foundation/Foundation.h>
#include <stdint.h>
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace net {
class CookieCreationTimeManagerTest : public PlatformTest {
public:
NSHTTPCookie* GetCookie(NSString* cookie_line) {
NSArray* cookies = [NSHTTPCookie
cookiesWithResponseHeaderFields:@{ @"Set-Cookie" : cookie_line }
forURL:[NSURL URLWithString:@"http://foo"]];
if ([cookies count] != 1)
return nil;
return [cookies objectAtIndex:0];
}
protected:
CookieCreationTimeManager creation_time_manager_;
};
TEST_F(CookieCreationTimeManagerTest, SetAndGet) {
NSHTTPCookie* cookie = GetCookie(@"A=B");
ASSERT_TRUE(cookie);
base::Time creation_time = base::Time::Now();
creation_time_manager_.SetCreationTime(cookie, creation_time);
EXPECT_EQ(creation_time, creation_time_manager_.GetCreationTime(cookie));
}
TEST_F(CookieCreationTimeManagerTest, GetFromSystemCookie) {
NSHTTPCookie* cookie = GetCookie(@"A=B");
// The creation time of a cookie that was never set through the
// CookieCreationTimeManager should be retrieved from the system with 1
// second precision.
base::Time time = creation_time_manager_.GetCreationTime(cookie);
base::Time now = base::Time::Now();
ASSERT_FALSE(time.is_null());
int64_t delta = (now - time).InMilliseconds();
// On iOS 8, the range is (0, 1000) ms. The intervals tested are actually
// 1200 ms to allow some imprecision.
EXPECT_GT(delta, -100);
EXPECT_LT(delta, 1100);
}
TEST_F(CookieCreationTimeManagerTest, MakeUniqueCreationTime) {
base::Time now = base::Time::Now();
// |now| is not used yet, so MakeUniqueCreationTime() should return that.
base::Time creation_time = creation_time_manager_.MakeUniqueCreationTime(now);
EXPECT_EQ(now, creation_time);
NSHTTPCookie* cookie1 = GetCookie(@"A=B");
ASSERT_TRUE(cookie1);
creation_time_manager_.SetCreationTime(cookie1, creation_time);
// |now| is used by cookie1, MakeUniqueCreationTime() should return the
// incremented value.
creation_time = creation_time_manager_.MakeUniqueCreationTime(now);
EXPECT_EQ(base::Time::FromInternalValue(now.ToInternalValue() + 1),
creation_time);
// Delete |cookie1|.
creation_time_manager_.DeleteCreationTime(cookie1);
// |now| is available again because |cookie1| was deleted.
creation_time = creation_time_manager_.MakeUniqueCreationTime(now);
EXPECT_EQ(now, creation_time);
creation_time_manager_.SetCreationTime(GetCookie(@"C=D"), creation_time);
// Override |C| with a cookie that has a different time, to make |now|
// available again.
creation_time_manager_.SetCreationTime(
GetCookie(@"C=E"), now - base::TimeDelta::FromMilliseconds(1));
// |now| is available again because |C| was overriden.
creation_time = creation_time_manager_.MakeUniqueCreationTime(now);
EXPECT_EQ(now, creation_time);
creation_time_manager_.SetCreationTime(GetCookie(@"F=G"), creation_time);
// Delete all creation times.
creation_time_manager_.Clear();
// |now| is available again because all creation times were cleared.
creation_time = creation_time_manager_.MakeUniqueCreationTime(now);
EXPECT_EQ(now, creation_time);
}
TEST_F(CookieCreationTimeManagerTest, MakeUniqueCreationTimeConflicts) {
base::Time creation_time = base::Time::Now();
int64_t time_internal_value = creation_time.ToInternalValue();
// Insert two cookies with consecutive times.
creation_time_manager_.SetCreationTime(GetCookie(@"A=B"), creation_time);
creation_time_manager_.SetCreationTime(
GetCookie(@"C=D"),
base::Time::FromInternalValue(time_internal_value + 1));
// MakeUniqueCreationTime() should insert at |time_internal_value + 2|.
base::Time time =
creation_time_manager_.MakeUniqueCreationTime(creation_time);
EXPECT_EQ(time_internal_value + 2, time.ToInternalValue());
creation_time_manager_.SetCreationTime(GetCookie(@"E=F"), time);
// Leave an available slot at |time_internal_value + 3| and insert another
// cookie at |time_internal_value + 4|.
creation_time_manager_.SetCreationTime(
GetCookie(@"G=H"),
base::Time::FromInternalValue(time_internal_value + 4));
// MakeUniqueCreationTime() should use the available slot.
time = creation_time_manager_.MakeUniqueCreationTime(creation_time);
EXPECT_EQ(time_internal_value + 3, time.ToInternalValue());
}
} // namespace net