#include "google_apis/calendar/calendar_api_requests.h"
#include <string>
#include <vector>
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "google_apis/calendar/calendar_api_response_types.h"
#include "google_apis/common/dummy_auth_service.h"
#include "google_apis/common/request_sender.h"
#include "google_apis/common/test_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/test/embedded_test_server/request_handler_util.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/test/test_shared_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace google_apis {
namespace calendar {
namespace {
const char kTestCalendarColorId[] = "5";
const char kTestPrimaryCalendarColorId[] = "14";
const char kTestPrimaryCalendarSummary[] = "test1@google.com";
const char kTestUserAgent[] = "test-user-agent";
}
class CalendarApiRequestsTest : public testing::Test {
public:
CalendarApiRequestsTest()
: test_shared_loader_factory_(
base::MakeRefCounted<network::TestSharedURLLoaderFactory>(
nullptr ,
true )) {}
void SetUp() override {
request_sender_ = std::make_unique<RequestSender>(
std::make_unique<DummyAuthService>(), test_shared_loader_factory_,
task_environment_.GetMainThreadTaskRunner(), kTestUserAgent,
TRAFFIC_ANNOTATION_FOR_TESTS);
test_server_.RegisterRequestHandler(
base::BindRepeating(&CalendarApiRequestsTest::HandleDataFileRequest,
base::Unretained(this)));
ASSERT_TRUE(test_server_.Start());
url_generator_ = std::make_unique<CalendarApiUrlGenerator>();
url_generator_->SetBaseUrlForTesting(test_server_.base_url().spec());
}
void TearDown() override {
request_sender_.reset();
task_environment_.RunUntilIdle();
}
base::test::TaskEnvironment task_environment_{
base::test::TaskEnvironment::MainThreadType::IO};
net::EmbeddedTestServer test_server_;
std::unique_ptr<RequestSender> request_sender_;
std::unique_ptr<CalendarApiUrlGenerator> url_generator_;
scoped_refptr<network::TestSharedURLLoaderFactory>
test_shared_loader_factory_;
net::test_server::HttpRequest http_request_;
std::unique_ptr<net::test_server::HttpResponse> HandleDataFileRequest(
const net::test_server::HttpRequest& request) {
http_request_ = request;
if (net::test_server::ShouldHandle(http_request_,
"/calendar/v3/calendars")) {
return test_util::CreateHttpResponseFromFile(
test_util::GetTestFilePath("calendar/events.json"));
}
if (net::test_server::ShouldHandle(http_request_,
"/calendar/v3/users/me/calendarList")) {
return test_util::CreateHttpResponseFromFile(
test_util::GetTestFilePath("calendar/calendar_list.json"));
}
NOTREACHED();
}
};
TEST_F(CalendarApiRequestsTest, GetCalendarListRequest) {
ApiErrorCode error = OTHER_ERROR;
std::unique_ptr<CalendarList> calendars;
{
base::RunLoop run_loop;
auto request = std::make_unique<CalendarApiCalendarListRequest>(
request_sender_.get(), *url_generator_,
test_util::CreateQuitCallback(
&run_loop,
test_util::CreateCopyResultCallback(&error, &calendars)));
request_sender_->StartRequestWithAuthRetry(std::move(request));
run_loop.Run();
}
EXPECT_EQ(HTTP_SUCCESS, error);
EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
EXPECT_EQ(
"/calendar/v3/users/me/calendarList"
"?maxResults=250"
"&fields=etag%2Ckind%2Citems"
"(kind%2Cid%2Csummary%2CcolorId%2Cselected%2Cprimary)",
http_request_.relative_url);
ASSERT_TRUE(calendars.get());
EXPECT_EQ("calendar#calendarList", calendars->kind());
EXPECT_EQ(kTestPrimaryCalendarSummary, calendars->items()[0]->summary());
EXPECT_EQ(kTestPrimaryCalendarColorId, calendars->items()[0]->color_id());
EXPECT_EQ(true, calendars->items()[0]->selected());
EXPECT_EQ(true, calendars->items()[0]->primary());
}
TEST_F(CalendarApiRequestsTest, GetEventListRequest) {
ApiErrorCode error = OTHER_ERROR;
std::unique_ptr<EventList> events;
base::Time start;
base::Time end;
EXPECT_TRUE(base::Time::FromString("13 Jun 2021 10:00 GMT", &start));
EXPECT_TRUE(base::Time::FromString("16 Jun 2021 10:00 GMT", &end));
{
base::RunLoop run_loop;
auto request = std::make_unique<CalendarApiEventsRequest>(
request_sender_.get(), *url_generator_,
test_util::CreateQuitCallback(
&run_loop, test_util::CreateCopyResultCallback(&error, &events)),
start, end, "test1@google.com",
kTestCalendarColorId);
request_sender_->StartRequestWithAuthRetry(std::move(request));
run_loop.Run();
}
EXPECT_EQ(HTTP_SUCCESS, error);
EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
EXPECT_EQ(
"/calendar/v3/calendars/test1@google.com/events"
"?timeMin=2021-06-13T10%3A00%3A00.000Z"
"&timeMax=2021-06-16T10%3A00%3A00.000Z"
"&singleEvents=true"
"&maxAttendees=1"
"&maxResults=2500"
"&fields=timeZone%2Cetag%2Ckind%2Citems(id%2Ckind%"
"2Csummary%2CcolorId%2Cstatus%"
"2Cstart(date)%2Cend(date)%"
"2Cstart(dateTime)%2Cend(dateTime)%"
"2ChtmlLink%2Cattendees(responseStatus%2Cself)%2CattendeesOmitted%"
"2CconferenceData(conferenceId%2CentryPoints(entryPointType%2Curi))%"
"2Ccreator(self)%2Clocation)",
http_request_.relative_url);
ASSERT_TRUE(events.get());
EXPECT_EQ(events->time_zone(), "America/Los_Angeles");
base::Time::Exploded exploded;
events->items()[0]->start_time().date_time().LocalExplode(&exploded);
EXPECT_EQ(exploded.month, 11);
EXPECT_EQ(events->items()[0]->color_id(), "3");
EXPECT_EQ(events->items()[1]->color_id(), "3");
EXPECT_EQ(events->items()[2]->color_id(),
calendar::kInjectedColorIdPrefix + kTestCalendarColorId);
}
TEST_F(CalendarApiRequestsTest,
GetEventListRequestWithDefaultOptionalParameters) {
ApiErrorCode error = OTHER_ERROR;
std::unique_ptr<EventList> events;
base::Time start;
base::Time end;
EXPECT_TRUE(base::Time::FromString("13 Jun 2021 10:00 GMT", &start));
EXPECT_TRUE(base::Time::FromString("16 Jun 2021 10:00 GMT", &end));
{
base::RunLoop run_loop;
auto request = std::make_unique<CalendarApiEventsRequest>(
request_sender_.get(), *url_generator_,
test_util::CreateQuitCallback(
&run_loop, test_util::CreateCopyResultCallback(&error, &events)),
start, end);
request_sender_->StartRequestWithAuthRetry(std::move(request));
run_loop.Run();
}
EXPECT_EQ(HTTP_SUCCESS, error);
EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
EXPECT_EQ(
"/calendar/v3/calendars/primary/events"
"?timeMin=2021-06-13T10%3A00%3A00.000Z"
"&timeMax=2021-06-16T10%3A00%3A00.000Z"
"&singleEvents=true"
"&maxAttendees=1"
"&maxResults=2500"
"&fields=timeZone%2Cetag%2Ckind%2Citems(id%2Ckind%"
"2Csummary%2CcolorId%2Cstatus%"
"2Cstart(date)%2Cend(date)%"
"2Cstart(dateTime)%2Cend(dateTime)%"
"2ChtmlLink%2Cattendees(responseStatus%2Cself)%2CattendeesOmitted%"
"2CconferenceData(conferenceId%2CentryPoints(entryPointType%2Curi))%"
"2Ccreator(self)%2Clocation)",
http_request_.relative_url);
ASSERT_TRUE(events.get());
EXPECT_EQ(events->time_zone(), "America/Los_Angeles");
base::Time::Exploded exploded;
events->items()[0]->start_time().date_time().LocalExplode(&exploded);
EXPECT_EQ(exploded.month, 11);
EXPECT_EQ(events->items()[0]->color_id(), "3");
EXPECT_EQ(events->items()[1]->color_id(), "3");
EXPECT_EQ(events->items()[2]->color_id(), "");
}
TEST_F(CalendarApiRequestsTest,
GetEventListRequestWithExtraParametersAndAttachments) {
ApiErrorCode error = OTHER_ERROR;
std::unique_ptr<EventList> events;
base::Time start;
base::Time end;
EXPECT_TRUE(base::Time::FromString("13 Jun 2021 10:00 GMT", &start));
EXPECT_TRUE(base::Time::FromString("16 Jun 2021 10:00 GMT", &end));
{
base::RunLoop run_loop;
std::vector<EventType> event_types;
event_types.push_back(EventType::kDefault);
auto request = std::make_unique<CalendarApiEventsRequest>(
request_sender_.get(), *url_generator_,
test_util::CreateQuitCallback(
&run_loop, test_util::CreateCopyResultCallback(&error, &events)),
start, end, event_types,
"test",
"startTime",
true);
request_sender_->StartRequestWithAuthRetry(std::move(request));
run_loop.Run();
}
EXPECT_EQ(HTTP_SUCCESS, error);
EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
EXPECT_EQ(
"/calendar/v3/calendars/primary/events"
"?timeMin=2021-06-13T10%3A00%3A00.000Z"
"&timeMax=2021-06-16T10%3A00%3A00.000Z"
"&singleEvents=true"
"&maxResults=2500"
"&orderBy=startTime"
"&eventTypes=default"
"&experiment=test"
"&fields=timeZone%2Cetag%2Ckind%2Citems(id%2Ckind%"
"2Csummary%2CcolorId%2Cstatus%"
"2Cstart(date)%2Cend(date)%"
"2Cstart(dateTime)%2Cend(dateTime)%"
"2ChtmlLink%2Cattendees(responseStatus%2Cself)%2CattendeesOmitted%"
"2CconferenceData(conferenceId%2CentryPoints(entryPointType%2Curi))%"
"2Ccreator(self)%2Clocation%"
"2Cattachments(title%2CfileUrl%2CiconLink%2CfileId))",
http_request_.relative_url);
ASSERT_TRUE(events.get());
EXPECT_EQ(events->time_zone(), "America/Los_Angeles");
base::Time::Exploded exploded;
events->items()[0]->start_time().date_time().LocalExplode(&exploded);
EXPECT_EQ(exploded.month, 11);
EXPECT_EQ(events->items()[0]->color_id(), "3");
EXPECT_EQ(events->items()[1]->color_id(), "3");
EXPECT_EQ(events->items()[2]->color_id(), "");
}
TEST_F(CalendarApiRequestsTest, GetEventListRequestWithAttachments) {
ApiErrorCode error = OTHER_ERROR;
std::unique_ptr<EventList> events;
base::Time start;
base::Time end;
EXPECT_TRUE(base::Time::FromString("13 Jun 2021 10:00 GMT", &start));
EXPECT_TRUE(base::Time::FromString("16 Jun 2021 10:00 GMT", &end));
{
base::RunLoop run_loop;
auto request = std::make_unique<CalendarApiEventsRequest>(
request_sender_.get(), *url_generator_,
test_util::CreateQuitCallback(
&run_loop, test_util::CreateCopyResultCallback(&error, &events)),
start, end, true);
request_sender_->StartRequestWithAuthRetry(std::move(request));
run_loop.Run();
}
EXPECT_EQ(HTTP_SUCCESS, error);
EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method);
EXPECT_EQ(
"/calendar/v3/calendars/primary/events"
"?timeMin=2021-06-13T10%3A00%3A00.000Z"
"&timeMax=2021-06-16T10%3A00%3A00.000Z"
"&singleEvents=true"
"&maxAttendees=1"
"&maxResults=2500"
"&fields=timeZone%2Cetag%2Ckind%2Citems(id%2Ckind"
"%2Csummary%2CcolorId%2Cstatus"
"%2Cstart(date)%2Cend(date)"
"%2Cstart(dateTime)%2Cend(dateTime)"
"%2ChtmlLink%2Cattendees(responseStatus%2Cself)%2CattendeesOmitted"
"%2CconferenceData(conferenceId%2CentryPoints(entryPointType%2Curi))"
"%2Ccreator(self)%2Clocation"
"%2Cattachments(title%2CfileUrl%2CiconLink%2CfileId))",
http_request_.relative_url);
}
}
}