Skip to content

Commit

Permalink
[GCM] Adding AccountInfo structure to persist accounts mapped to GCM
Browse files Browse the repository at this point in the history
R=zea@chromium.org
BUG=374969

Review URL: https://codereview.chromium.org/423583004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@286420 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
fgorski@chromium.org committed Jul 30, 2014
1 parent d1024ef commit a7b0064
Show file tree
Hide file tree
Showing 4 changed files with 270 additions and 0 deletions.
109 changes: 109 additions & 0 deletions google_apis/gcm/engine/account_info.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// 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 "google_apis/gcm/engine/account_info.h"

#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"

namespace gcm {

namespace {

const char kSeparator[] = "&";
uint32 kEmailIndex = 0;
uint32 kMessageTypeIndex = 1;
uint32 kMessageIdIndex = 2;
uint32 kMessageTimestampIndex = 3;
uint32 kSizeWithNoMessage = kMessageTypeIndex + 1;
uint32 kSizeWithMessage = kMessageTimestampIndex + 1;

std::string MessageTypeToString(AccountInfo::MessageType type) {
switch (type) {
case AccountInfo::MSG_NONE:
return "none";
case AccountInfo::MSG_ADD:
return "add";
case AccountInfo::MSG_REMOVE:
return "remove";
default:
NOTREACHED();
}
return "";
}

AccountInfo::MessageType StringToMessageType(const std::string& type) {
if (type.compare("add") == 0)
return AccountInfo::MSG_ADD;
if (type.compare("remove") == 0)
return AccountInfo::MSG_REMOVE;
return AccountInfo::MSG_NONE;
}

} // namespace

AccountInfo::AccountInfo() {
}

AccountInfo::~AccountInfo() {
}

std::string AccountInfo::SerializeAsString() const {
std::string value;
value.append(email);
value.append(kSeparator);
value.append(MessageTypeToString(last_message_type));
if (last_message_type != MSG_NONE) {
value.append(kSeparator);
value.append(last_message_id);
value.append(kSeparator);
value.append(base::Int64ToString(last_message_timestamp.ToInternalValue()));
}

return value;
}

bool AccountInfo::ParseFromString(const std::string& value) {
std::vector<std::string> values;
Tokenize(value, kSeparator, &values);
if (values.size() != kSizeWithNoMessage &&
values.size() != kSizeWithMessage) {
return false;
}

if (values[kEmailIndex].empty() ||
values[kMessageTypeIndex].empty()) {
return false;
}

if (values.size() == kSizeWithMessage &&
(values[kMessageIdIndex].empty() ||
values[kMessageTimestampIndex].empty())) {
return false;
}

if (values.size() == kSizeWithMessage) {
int64 timestamp = 0LL;
if (!base::StringToInt64(values[kMessageTimestampIndex], &timestamp))
return false;

MessageType message_type = StringToMessageType(values[kMessageTypeIndex]);
if (message_type == MSG_NONE)
return false;

last_message_type = message_type;
last_message_id = values[kMessageIdIndex];
last_message_timestamp = base::Time::FromInternalValue(timestamp);
} else {
last_message_type = MSG_NONE;
last_message_id.clear();
last_message_timestamp = base::Time();
}

email = values[kEmailIndex];

return true;
}

} // namespace gcm
49 changes: 49 additions & 0 deletions google_apis/gcm/engine/account_info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// 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.

#ifndef GOOGLE_APIS_GCM_ENGINE_ACCOUNT_INFO_H_
#define GOOGLE_APIS_GCM_ENGINE_ACCOUNT_INFO_H_

#include <string>

#include "base/basictypes.h"
#include "base/time/time.h"
#include "google_apis/gcm/base/gcm_export.h"

namespace gcm {

// Stores information about Account and a last message sent with the information
// about that account.
struct GCM_EXPORT AccountInfo {
// Indicates whether a message, if sent, was adding or removing account
// mapping.
enum MessageType {
MSG_NONE, // No message has been sent.
MSG_ADD, // Account was mapped to device by the message.
MSG_REMOVE, // Account mapping to device was removed by the message.
};

AccountInfo();
~AccountInfo();

// Serializes account info to string without |account_id|.
std::string SerializeAsString() const;
// Parses account info from store, without |account_id|.
bool ParseFromString(const std::string& value);

// Gaia ID of the account.
std::string account_id;
// Email address of the tracked account.
std::string email;
// Type of the last mapping message sent to GCM.
MessageType last_message_type;
// ID of the last mapping message sent to GCM.
std::string last_message_id;
// Timestamp of when the last mapping message was sent to GCM.
base::Time last_message_timestamp;
};

} // namespace gcm

#endif // GOOGLE_APIS_GCM_ENGINE_ACCOUNT_INFO_H_
109 changes: 109 additions & 0 deletions google_apis/gcm/engine/account_info_unittest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// 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 <string>

#include "google_apis/gcm/engine/account_info.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace gcm {

namespace {

TEST(AccountInfoTest, SerializeAccountInfo) {
AccountInfo account_info;
account_info.account_id = "acc_id";
account_info.email = "test@example.com";
account_info.last_message_id = "last_message_id_1";
account_info.last_message_type = AccountInfo::MSG_ADD;
account_info.last_message_timestamp = base::Time::FromInternalValue(
1305797421259935LL); // Arbitrary timestamp.

EXPECT_EQ("test@example.com&add&last_message_id_1&1305797421259935",
account_info.SerializeAsString());

account_info.account_id = "acc_id2";
account_info.email = "test@gmail.com";
account_info.last_message_id = "last_message_id_2";
account_info.last_message_type = AccountInfo::MSG_REMOVE;
account_info.last_message_timestamp =
base::Time::FromInternalValue(1305734521259935LL); // Other timestamp.

EXPECT_EQ("test@gmail.com&remove&last_message_id_2&1305734521259935",
account_info.SerializeAsString());

account_info.last_message_type = AccountInfo::MSG_NONE;

EXPECT_EQ("test@gmail.com&none", account_info.SerializeAsString());
}

TEST(AccountInfoTest, DeserializeAccountInfo) {
AccountInfo account_info;
account_info.account_id = "acc_id";
EXPECT_TRUE(account_info.ParseFromString(
"test@example.com&add&last_message_id_1&1305797421259935"));
EXPECT_EQ("acc_id", account_info.account_id);
EXPECT_EQ("test@example.com", account_info.email);
EXPECT_EQ(AccountInfo::MSG_ADD, account_info.last_message_type);
EXPECT_EQ("last_message_id_1", account_info.last_message_id);
EXPECT_EQ(base::Time::FromInternalValue(1305797421259935LL),
account_info.last_message_timestamp);

EXPECT_TRUE(account_info.ParseFromString(
"test@gmail.com&remove&last_message_id_2&1305734521259935"));
EXPECT_EQ("acc_id", account_info.account_id);
EXPECT_EQ("test@gmail.com", account_info.email);
EXPECT_EQ(AccountInfo::MSG_REMOVE, account_info.last_message_type);
EXPECT_EQ("last_message_id_2", account_info.last_message_id);
EXPECT_EQ(base::Time::FromInternalValue(1305734521259935LL),
account_info.last_message_timestamp);

EXPECT_TRUE(account_info.ParseFromString("test@gmail.com&none"));
EXPECT_EQ("acc_id", account_info.account_id);
EXPECT_EQ("test@gmail.com", account_info.email);
EXPECT_EQ(AccountInfo::MSG_NONE, account_info.last_message_type);
EXPECT_EQ("", account_info.last_message_id);
EXPECT_EQ(base::Time(), account_info.last_message_timestamp);
}

TEST(AccountInfoTest, DeserializeAccountInfoInvalidInput) {
AccountInfo account_info;
account_info.account_id = "acc_id";
// Too many agruments.
EXPECT_FALSE(account_info.ParseFromString(
"test@example.com&add&last_message_id_1&1305797421259935&stuff_here"));
// Too few arguments.
EXPECT_FALSE(account_info.ParseFromString(
"test@example.com&remove&last_message_id_1"));
// Too few arguments.
EXPECT_FALSE(account_info.ParseFromString(
"test@example.com"));
// Missing email.
EXPECT_FALSE(account_info.ParseFromString(
"&remove&last_message_id_2&1305734521259935"));
// Missing message type.
EXPECT_FALSE(account_info.ParseFromString(
"test@gmail.com&&last_message_id_2&1305734521259935"));
// Unkown message type.
EXPECT_FALSE(account_info.ParseFromString(
"test@gmail.com&random&last_message_id_2&1305734521259935"));
// Message type is none when message details specified.
EXPECT_FALSE(account_info.ParseFromString(
"test@gmail.com&none&last_message_id_2&1305734521259935"));
// Message type is messed up, but we have no message -- that's OK.
EXPECT_TRUE(account_info.ParseFromString(
"test@gmail.com&random"));
// Missing last message ID.
EXPECT_FALSE(account_info.ParseFromString(
"test@gmail.com&remove&&1305734521259935"));
// Missing last message timestamp.
EXPECT_FALSE(account_info.ParseFromString(
"test@gmail.com&remove&last_message_id&"));
// Last message timestamp not parseable.
EXPECT_FALSE(account_info.ParseFromString(
"test@gmail.com&remove&last_message_id&asdfjlk"));
}

} // namespace
} // namespace gcm
3 changes: 3 additions & 0 deletions google_apis/gcm/gcm.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
'base/mcs_util.h',
'base/socket_stream.cc',
'base/socket_stream.h',
'engine/account_info.cc',
'engine/account_info.h',
'engine/checkin_request.cc',
'engine/checkin_request.h',
'engine/connection_factory.cc',
Expand Down Expand Up @@ -159,6 +161,7 @@
'base/mcs_message_unittest.cc',
'base/mcs_util_unittest.cc',
'base/socket_stream_unittest.cc',
'engine/account_info_unittest.cc',
'engine/checkin_request_unittest.cc',
'engine/connection_factory_impl_unittest.cc',
'engine/connection_handler_impl_unittest.cc',
Expand Down

0 comments on commit a7b0064

Please sign in to comment.