File: calendar_keyed_service_unittest.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (346 lines) | stat: -rw-r--r-- 14,170 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/calendar/calendar_keyed_service.h"

#include <memory>
#include <vector>

#include "ash/calendar/calendar_controller.h"
#include "ash/shell.h"
#include "base/strings/strcat.h"
#include "base/test/bind.h"
#include "base/time/time.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/browser/ash/calendar/calendar_keyed_service_factory.h"
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/account_id/account_id.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "google_apis/calendar/calendar_api_requests.h"
#include "google_apis/common/api_error_codes.h"
#include "google_apis/common/dummy_auth_service.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_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 ash {
namespace {

constexpr char kPrimaryProfileName[] = "primary_profile";
constexpr char kSecondaryProfileName[] = "secondary_profile";
constexpr GaiaId::Literal kFakeGaia2("fakegaia2");
constexpr char kTestGroupCalendarId[] =
    "oz2iwbysdg20tn8zdjvtqnkj12test@group.calendar.google.com";
constexpr char kTestGroupCalendarColorId[] = "3";
constexpr char kTestUserAgent[] = "test-user-agent";

}  // namespace

class CalendarKeyedServiceTest : public BrowserWithTestWindowTest {
 public:
  CalendarKeyedServiceTest() = default;
  CalendarKeyedServiceTest(const CalendarKeyedServiceTest& other) = delete;
  CalendarKeyedServiceTest& operator=(const CalendarKeyedServiceTest& other) =
      delete;
  ~CalendarKeyedServiceTest() override = default;

  void SetUp() override {
    ProfileHelper::SetProfileToUserForTestingEnabled(true);
    BrowserWithTestWindowTest::SetUp();
  }

  void TearDown() override {
    BrowserWithTestWindowTest::TearDown();
    ProfileHelper::SetProfileToUserForTestingEnabled(false);
  }

  std::optional<std::string> GetDefaultProfileName() override {
    return kPrimaryProfileName;
  }

  TestingProfile* CreateSecondaryProfile() {
    LogIn(kSecondaryProfileName, kFakeGaia2);
    return CreateProfile(kSecondaryProfileName);
  }
};

class CalendarKeyedServiceIOTest : public testing::Test {
 public:
  CalendarKeyedServiceIOTest()
      : test_shared_loader_factory_(
            base::MakeRefCounted<network::TestSharedURLLoaderFactory>(
                /*network_service=*/nullptr,
                /*is_trusted=*/true)) {}

  CalendarKeyedServiceIOTest(const CalendarKeyedServiceIOTest& other) = delete;
  CalendarKeyedServiceIOTest& operator=(
      const CalendarKeyedServiceIOTest& other) = delete;
  ~CalendarKeyedServiceIOTest() override = default;

  void SetUp() override {
    request_sender_ = std::make_unique<google_apis::RequestSender>(
        std::make_unique<google_apis::DummyAuthService>(),
        test_shared_loader_factory_,
        task_environment_.GetMainThreadTaskRunner(), kTestUserAgent,
        TRAFFIC_ANNOTATION_FOR_TESTS);

    test_server_.RegisterRequestHandler(base::BindRepeating(
        &CalendarKeyedServiceIOTest::HandleRequest, base::Unretained(this)));
    ASSERT_TRUE(test_server_.Start());
  }

  void TearDown() override {
    // Deleting the sender here will delete all request objects.
    request_sender_.reset();

    // Wait for any DeleteSoon tasks to run.
    task_environment_.RunUntilIdle();
  }

  // Returns the response from a mock json file in google_apis/test/data/
  // depending on whether the request is for the calendar list or the event
  // list.
  std::unique_ptr<net::test_server::HttpResponse> HandleRequest(
      const net::test_server::HttpRequest& request) {
    if (net::test_server::ShouldHandle(request,
                                       "/calendar/v3/users/me/calendarList")) {
      return google_apis::test_util::CreateHttpResponseFromFile(
          google_apis::test_util::GetTestFilePath(
              "calendar/calendar_list.json"));
    }
    if (net::test_server::ShouldHandle(request,
                                       "/calendar/v3/calendars/primary")) {
      return google_apis::test_util::CreateHttpResponseFromFile(
          google_apis::test_util::GetTestFilePath("calendar/events.json"));
    }
    if (net::test_server::ShouldHandle(
            request,
            base::StrCat({"/calendar/v3/calendars/", kTestGroupCalendarId}))) {
      return google_apis::test_util::CreateHttpResponseFromFile(
          google_apis::test_util::GetTestFilePath(
              "calendar/group_calendar_events.json"));
    }
    NOTREACHED();
  }

  content::BrowserTaskEnvironment task_environment_{
      base::test::TaskEnvironment::MainThreadType::IO};
  net::EmbeddedTestServer test_server_;
  std::unique_ptr<google_apis::RequestSender> request_sender_;
  scoped_refptr<network::TestSharedURLLoaderFactory>
      test_shared_loader_factory_;
};

class NoProfileCalendarKeyedServiceTest : public CalendarKeyedServiceTest {
 public:
  NoProfileCalendarKeyedServiceTest() = default;
  NoProfileCalendarKeyedServiceTest(
      const NoProfileCalendarKeyedServiceTest& other) = delete;
  NoProfileCalendarKeyedServiceTest& operator=(
      const NoProfileCalendarKeyedServiceTest& other) = delete;
  ~NoProfileCalendarKeyedServiceTest() override = default;

  // CalendarKeyedServiceTest:
  std::optional<std::string> GetDefaultProfileName() override {
    return std::nullopt;
  }
};

// Calendar service does not support guest user.
TEST_F(NoProfileCalendarKeyedServiceTest, GuestUserProfile) {
  // Construct a guest session profile.
  TestingProfile::Builder guest_profile_builder;
  guest_profile_builder.SetGuestSession();
  guest_profile_builder.SetProfileName("guest_profile");
  guest_profile_builder.AddTestingFactories({});
  std::unique_ptr<TestingProfile> guest_profile = guest_profile_builder.Build();

  // Profile should be created for guest sessions.
  ASSERT_TRUE(guest_profile);
  CalendarKeyedService* const guest_profile_service =
      CalendarKeyedServiceFactory::GetInstance()->GetService(
          // Use OTR profile for guest.
          guest_profile->GetPrimaryOTRProfile(/*create_if_needed=*/true));
  EXPECT_FALSE(guest_profile_service);
}

// Calendar service does not support incognito user.
TEST_F(CalendarKeyedServiceTest, OffTheRecordProfile) {
  // Service instances should be created for on the record profiles.
  CalendarKeyedService* const primary_profile_service =
      CalendarKeyedServiceFactory::GetInstance()->GetService(GetProfile());
  EXPECT_TRUE(primary_profile_service);

  // Construct an incognito profile from the primary profile.
  TestingProfile::Builder incognito_primary_profile_builder;
  incognito_primary_profile_builder.SetProfileName(
      GetProfile()->GetProfileUserName());
  Profile* const incognito_primary_profile =
      incognito_primary_profile_builder.BuildIncognito(GetProfile());
  ASSERT_TRUE(incognito_primary_profile);
  EXPECT_TRUE(incognito_primary_profile->IsOffTheRecord());

  // Service instances should *not* typically be created for OTR profiles.
  CalendarKeyedService* const incognito_primary_profile_service =
      CalendarKeyedServiceFactory::GetInstance()->GetService(
          incognito_primary_profile);
  EXPECT_FALSE(incognito_primary_profile_service);
}

// Calendar service should support switching users.
TEST_F(CalendarKeyedServiceTest, SecondaryUserProfile) {
  CalendarKeyedService* const primary_calendar_service =
      CalendarKeyedServiceFactory::GetInstance()->GetService(GetProfile());

  TestingProfile* const second_profile = CreateSecondaryProfile();

  CalendarKeyedService* const secondary_calendar_service =
      CalendarKeyedServiceFactory::GetInstance()->GetService(second_profile);
  // Just creating a secondary profile shouldn't change the active client.
  EXPECT_EQ(ash::Shell::Get()->calendar_controller()->GetClient(),
            primary_calendar_service->client());

  // Switching the active user should change the active client (multi-user
  // support).
  SwitchActiveUser(kSecondaryProfileName);
  EXPECT_EQ(ash::Shell::Get()->calendar_controller()->GetClient(),
            secondary_calendar_service->client());
}

TEST_F(CalendarKeyedServiceIOTest, GetCalendarList) {
  // Creating the service with a test profile and account ID.
  std::unique_ptr<TestingProfile> profile = std::make_unique<TestingProfile>();
  auto calendar_service = std::make_unique<CalendarKeyedService>(
      profile.get(), AccountId::FromUserEmail("test@email.com"));

  calendar_service->set_sender_for_testing(std::move(request_sender_));
  calendar_service->SetUrlForTesting(test_server_.base_url().spec());

  // The error code should be overwritten by `HTTP_SUCCESS` after the
  // `GetCalendarList` call.
  google_apis::ApiErrorCode error = google_apis::OTHER_ERROR;

  // Declaring the mock 'GetCalendarList' result.
  std::unique_ptr<google_apis::calendar::CalendarList> calendar_list;

  {
    base::RunLoop run_loop;
    calendar_service->GetCalendarList(
        google_apis::test_util::CreateQuitCallback(
            &run_loop, google_apis::test_util::CreateCopyResultCallback(
                           &error, &calendar_list)));
    run_loop.Run();
  }

  // Verify that the result has expected values.
  EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
  EXPECT_EQ("calendar#calendarList", calendar_list->kind());
  EXPECT_EQ(3U, calendar_list->items().size());
  const google_apis::calendar::SingleCalendar& calendar =
      *calendar_list->items()[1];
  EXPECT_EQ(calendar.id(),
            "google.com_zu35dc5syt5k0fddetqqfggb75test@"
            "group.calendar.google.com");
  EXPECT_FALSE(calendar.selected());
}

TEST_F(CalendarKeyedServiceIOTest, GetEventListForDefaultCalendar) {
  // Creating the service with some testing profile and account id. Since in
  // this test we are using the IO thread, the service can not be created from
  // the factory.
  std::unique_ptr<TestingProfile> profile = std::make_unique<TestingProfile>();
  auto calendar_service = std::make_unique<CalendarKeyedService>(
      profile.get(), AccountId::FromUserEmail("test@email.com"));

  calendar_service->set_sender_for_testing(std::move(request_sender_));
  calendar_service->SetUrlForTesting(test_server_.base_url().spec());

  // The error code should be overwritten by `HTTP_SUCCESS` after the
  // `GetEventList` call.
  google_apis::ApiErrorCode error = google_apis::OTHER_ERROR;

  // This events should be the mock response after the `GetEventList` call.
  std::unique_ptr<google_apis::calendar::EventList> events;

  base::Time start;
  base::Time end;
  ASSERT_TRUE(base::Time::FromString("13 Jun 2021 10:00 GMT", &start));
  ASSERT_TRUE(base::Time::FromString("16 Jun 2021 10:00 GMT", &end));

  {
    base::RunLoop run_loop;
    calendar_service->GetEventList(
        google_apis::test_util::CreateQuitCallback(
            &run_loop,
            google_apis::test_util::CreateCopyResultCallback(&error, &events)),
        start, end);
    run_loop.Run();
  }

  EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
  const google_apis::calendar::CalendarEvent& event = *events->items()[0];
  EXPECT_EQ(event.summary(), "Mobile weekly team meeting ");
  EXPECT_EQ(event.id(), "or8221sirt4ogftest");
  EXPECT_EQ(events->time_zone(), "America/Los_Angeles");
}

TEST_F(CalendarKeyedServiceIOTest, GetEventListForNonDefaultCalendar) {
  // Creating the service with a test profile and account ID.
  std::unique_ptr<TestingProfile> profile = std::make_unique<TestingProfile>();
  auto calendar_service = std::make_unique<CalendarKeyedService>(
      profile.get(), AccountId::FromUserEmail("test@email.com"));

  calendar_service->set_sender_for_testing(std::move(request_sender_));
  calendar_service->SetUrlForTesting(test_server_.base_url().spec());

  // The error code should be overwritten by `HTTP_SUCCESS` after the
  // `GetEventList` call.
  google_apis::ApiErrorCode error = google_apis::OTHER_ERROR;

  // Declaring the mock 'GetEventList' result.
  std::unique_ptr<google_apis::calendar::EventList> events;

  base::Time start;
  base::Time end;
  ASSERT_TRUE(base::Time::FromString("19 Jan 2024 5:00 GMT", &start));
  ASSERT_TRUE(base::Time::FromString("01 Feb 2024 5:00 GMT", &end));

  {
    base::RunLoop run_loop;
    calendar_service->GetEventList(
        google_apis::test_util::CreateQuitCallback(
            &run_loop,
            google_apis::test_util::CreateCopyResultCallback(&error, &events)),
        start, end, /*calendar_id=*/kTestGroupCalendarId,
        /*calendar_color_id=*/kTestGroupCalendarColorId);
    run_loop.Run();
  }

  EXPECT_EQ(google_apis::HTTP_SUCCESS, error);
  const google_apis::calendar::CalendarEvent& event = *events->items()[1];
  // Verify that a returned event matches one at the same position on the mock
  // group calendar events list.
  EXPECT_EQ(event.summary(), "Strawberry Refreshers @ 4th Floor Cafe");
  EXPECT_EQ(event.id(), "z27t6aqhloxm19wpwcrk7gyycy");
  // Verify that the event color ID has not been injected with the value passed
  // in for calendar_color_id because the field was already populated.
  EXPECT_EQ(event.color_id(), "7");

  const google_apis::calendar::CalendarEvent& event2 = *events->items()[2];
  // Verify that a returned event matches one at the same position on the mock
  // group calendar events list.
  EXPECT_EQ(event2.summary(), "Popcorn Pop-Up");
  EXPECT_EQ(event2.id(), "kff9ghr5gt8fhhechomqnld9et");
  // Verify that the event color ID is now equal to the value passed into
  // calendar_color_id (prepended by a marker).
  EXPECT_EQ(event2.color_id(), google_apis::calendar::kInjectedColorIdPrefix +
                                   kTestGroupCalendarColorId);
}

}  // namespace ash