blob: f117c3e2d709a6e49831d23c34174491e0f4bb18 [file] [log] [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_NET_COOKIES_SYSTEM_COOKIE_STORE_UNITTEST_TEMPLATE_H_
#define IOS_NET_COOKIES_SYSTEM_COOKIE_STORE_UNITTEST_TEMPLATE_H_
#import <Foundation/Foundation.h>
#import <optional>
#import "base/barrier_closure.h"
#import "base/functional/bind.h"
#import "base/functional/callback.h"
#import "base/memory/ptr_util.h"
#import "base/run_loop.h"
#import "base/test/ios/wait_util.h"
#import "ios/net/cookies/cookie_store_ios_test_util.h"
#import "ios/net/cookies/system_cookie_store.h"
#import "net/base/apple/url_conversions.h"
#import "testing/gtest/include/gtest/gtest.h"
#import "testing/gtest_mac.h"
#import "testing/platform_test.h"
#import "url/gurl.h"
namespace net {
// This class defines tests that implementations of SystemCookieStore should
// pass in order to be conformant.
// To use this test, A delegate class should be created for each implementation.
// The delegate class has to implement the following functions:
// GetCookieStore()
// Returns a SystemCookieStore implementation object.
// bool IsCookieSet(NSHttpCookie cookie, NSURL url)
// Returns wether |cookie| is set for |url| in the internal cookie store or
// not.
// ClearCookies()
// Deletes all cookies in the internal cookie store.
// int CookiesCount()
// Returns the number of cookies set in the internal cookie store.
template <typename SystemCookieStoreTestDelegate>
class SystemCookieStoreTest : public PlatformTest {
public:
SystemCookieStoreTest()
: test_cookie_url1_([NSURL URLWithString:@"http://foo.google.com/bar"]),
test_cookie_url2_([NSURL URLWithString:@"http://bar.xyz.abc/"]),
test_cookie_url3_([NSURL URLWithString:@"http://123.foo.bar/"]) {
ClearCookies();
}
// Gets the SystemCookieStore implementation class instance.
SystemCookieStore* GetCookieStore() { return delegate_.GetCookieStore(); }
// Returns wether |system_cookie| is set in |delegate_| cookiestore or not.
bool IsCookieSet(NSHTTPCookie* system_cookie, NSURL* url) {
return delegate_.IsCookieSet(system_cookie, url);
}
// Clears the |delegate_| cookie store.
void ClearCookies() { delegate_.ClearCookies(); }
// Returns the number of cookies set in the |delegate_| cookie store.
int CookiesCount() { return delegate_.CookiesCount(); }
// Creates a cookie with `name`, `value` and `url`.
NSHTTPCookie* CreateCookie(NSString* name, NSString* value, NSURL* url) {
return [NSHTTPCookie cookieWithProperties:@{
NSHTTPCookiePath : url.path,
NSHTTPCookieName : name,
NSHTTPCookieValue : value,
NSHTTPCookieDomain : url.host,
}];
}
// Sets |cookie| in the SystemCookieStore, doesn't care about
// callback and doesn't set creation time.
void SetCookieInStoreWithNoCallback(NSHTTPCookie* cookie) {
base::RunLoop run_loop;
GetCookieStore()->SetCookieAsync(cookie,
/*optional_creation_time=*/std::nullopt,
run_loop.QuitClosure());
run_loop.Run();
}
protected:
NSURL* test_cookie_url1_;
NSURL* test_cookie_url2_;
NSURL* test_cookie_url3_;
private:
SystemCookieStoreTestDelegate delegate_;
};
TYPED_TEST_SUITE_P(SystemCookieStoreTest);
TYPED_TEST_P(SystemCookieStoreTest, SetCookieAsync) {
NSHTTPCookie* system_cookie =
this->CreateCookie(@"a", @"b", this->test_cookie_url1_);
this->SetCookieInStoreWithNoCallback(system_cookie);
EXPECT_TRUE(this->IsCookieSet(system_cookie, this->test_cookie_url1_));
}
// Tests that inserting multiple cookies with identical creation times works.
TYPED_TEST_P(SystemCookieStoreTest, SetCookieAsyncWithIdenticalCreationTime) {
NSHTTPCookie* system_cookie_1 =
this->CreateCookie(@"a", @"b", this->test_cookie_url1_);
NSHTTPCookie* system_cookie_2 =
this->CreateCookie(@"c", @"d", this->test_cookie_url2_);
SystemCookieStore* cookie_store = this->GetCookieStore();
const base::Time creation_time = base::Time::Now();
base::RunLoop run_loop;
base::RepeatingClosure closure =
base::BarrierClosure(2, run_loop.QuitClosure());
cookie_store->SetCookieAsync(system_cookie_1, creation_time, closure);
cookie_store->SetCookieAsync(system_cookie_2, creation_time, closure);
run_loop.Run();
EXPECT_TRUE(this->IsCookieSet(system_cookie_1, this->test_cookie_url1_));
EXPECT_TRUE(this->IsCookieSet(system_cookie_2, this->test_cookie_url2_));
}
// Tests cases of GetAllCookiesAsync and GetCookiesForURLAsync.
TYPED_TEST_P(SystemCookieStoreTest, GetCookiesAsync) {
SystemCookieStore* cookie_store = this->GetCookieStore();
NSMutableDictionary* input_cookies = [[NSMutableDictionary alloc] init];
NSHTTPCookie* system_cookie =
this->CreateCookie(@"a", @"b", this->test_cookie_url1_);
[input_cookies setValue:system_cookie forKey:@"a"];
this->SetCookieInStoreWithNoCallback(system_cookie);
system_cookie = this->CreateCookie(@"x", @"d", this->test_cookie_url2_);
[input_cookies setValue:system_cookie forKey:@"x"];
this->SetCookieInStoreWithNoCallback(system_cookie);
system_cookie = this->CreateCookie(@"l", @"m", this->test_cookie_url3_);
[input_cookies setValue:system_cookie forKey:@"l"];
this->SetCookieInStoreWithNoCallback(system_cookie);
// Test GetCookieForURLAsync.
NSHTTPCookie* input_cookie = [input_cookies valueForKey:@"a"];
{
base::RunLoop run_loop;
__block NSArray<NSHTTPCookie*>* result_cookies = nil;
cookie_store->GetCookiesForURLAsync(
GURLWithNSURL(this->test_cookie_url1_),
base::BindOnce(^(NSArray<NSHTTPCookie*>* result) {
result_cookies = result;
}).Then(run_loop.QuitClosure()));
run_loop.Run();
EXPECT_EQ(1u, result_cookies.count);
NSHTTPCookie* result_cookie = result_cookies[0];
EXPECT_NSEQ(input_cookie.name, result_cookie.name);
EXPECT_NSEQ(input_cookie.value, result_cookie.value);
}
// Test GetAllCookies
{
base::RunLoop run_loop;
__block NSArray<NSHTTPCookie*>* result_cookies = nil;
cookie_store->GetAllCookiesAsync(
base::BindOnce(^(NSArray<NSHTTPCookie*>* result) {
result_cookies = result;
}).Then(run_loop.QuitClosure()));
run_loop.Run();
EXPECT_EQ(3u, result_cookies.count);
for (NSHTTPCookie* cookie in result_cookies) {
NSHTTPCookie* existing_cookie = [input_cookies valueForKey:cookie.name];
EXPECT_TRUE(existing_cookie);
EXPECT_NSEQ(existing_cookie.name, cookie.name);
EXPECT_NSEQ(existing_cookie.value, cookie.value);
EXPECT_NSEQ(existing_cookie.domain, cookie.domain);
}
}
}
// Tests deleting cookies for different URLs and for different
// cookie key/value pairs.
TYPED_TEST_P(SystemCookieStoreTest, DeleteCookiesAsync) {
SystemCookieStore* cookie_store = this->GetCookieStore();
NSHTTPCookie* system_cookie1 =
this->CreateCookie(@"a", @"b", this->test_cookie_url1_);
this->SetCookieInStoreWithNoCallback(system_cookie1);
NSHTTPCookie* system_cookie2 =
this->CreateCookie(@"x", @"d", this->test_cookie_url2_);
cookie_store->SetCookieAsync(system_cookie2,
/*optional_creation_time=*/std::nullopt,
SystemCookieStore::SystemCookieCallback());
this->SetCookieInStoreWithNoCallback(system_cookie2);
EXPECT_EQ(2, this->CookiesCount());
EXPECT_TRUE(this->IsCookieSet(system_cookie2, this->test_cookie_url2_));
{
base::RunLoop run_loop;
cookie_store->DeleteCookieAsync(system_cookie2, run_loop.QuitClosure());
run_loop.Run();
EXPECT_FALSE(this->IsCookieSet(system_cookie2, this->test_cookie_url2_));
EXPECT_EQ(1, this->CookiesCount());
}
{
base::RunLoop run_loop;
cookie_store->DeleteCookieAsync(system_cookie1, run_loop.QuitClosure());
run_loop.Run();
EXPECT_FALSE(this->IsCookieSet(system_cookie1, this->test_cookie_url1_));
EXPECT_EQ(0, this->CookiesCount());
}
}
TYPED_TEST_P(SystemCookieStoreTest, ClearCookiesAsync) {
SystemCookieStore* cookie_store = this->GetCookieStore();
this->SetCookieInStoreWithNoCallback(
this->CreateCookie(@"a", @"b", this->test_cookie_url1_));
this->SetCookieInStoreWithNoCallback(
this->CreateCookie(@"x", @"d", this->test_cookie_url2_));
EXPECT_EQ(2, this->CookiesCount());
base::RunLoop run_loop;
cookie_store->ClearStoreAsync(run_loop.QuitClosure());
run_loop.Run();
EXPECT_EQ(0, this->CookiesCount());
}
TYPED_TEST_P(SystemCookieStoreTest, GetCookieAcceptPolicy) {
SystemCookieStore* cookie_store = this->GetCookieStore();
EXPECT_EQ([NSHTTPCookieStorage sharedHTTPCookieStorage].cookieAcceptPolicy,
cookie_store->GetCookieAcceptPolicy());
[NSHTTPCookieStorage sharedHTTPCookieStorage].cookieAcceptPolicy =
NSHTTPCookieAcceptPolicyNever;
EXPECT_EQ(NSHTTPCookieAcceptPolicyNever,
cookie_store->GetCookieAcceptPolicy());
[NSHTTPCookieStorage sharedHTTPCookieStorage].cookieAcceptPolicy =
NSHTTPCookieAcceptPolicyAlways;
EXPECT_EQ(NSHTTPCookieAcceptPolicyAlways,
cookie_store->GetCookieAcceptPolicy());
}
REGISTER_TYPED_TEST_SUITE_P(SystemCookieStoreTest,
SetCookieAsync,
SetCookieAsyncWithIdenticalCreationTime,
GetCookiesAsync,
DeleteCookiesAsync,
ClearCookiesAsync,
GetCookieAcceptPolicy);
} // namespace net
#endif // IOS_NET_COOKIES_SYSTEM_COOKIE_STORE_UNITTEST_TEMPLATE_H_