Skip to content

Commit

Permalink
Improve behaviour when unitialized
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-p committed Sep 11, 2019
1 parent 97004b4 commit 88fafa1
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 6 deletions.
32 changes: 26 additions & 6 deletions psicash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,11 @@ constexpr int HTTPResult::CRITICAL_ERROR;
constexpr int HTTPResult::RECOVERABLE_ERROR;

PsiCash::PsiCash()
: server_port_(0), make_http_request_fn_(nullptr) {
: test_(false),
initialized_(false),
server_port_(0),
user_data_(std::make_unique<UserData>()),
make_http_request_fn_(nullptr) {
}

PsiCash::~PsiCash() {
Expand Down Expand Up @@ -111,9 +115,16 @@ Error PsiCash::Init(const string& user_agent, const string& file_store_root,
// May still be null.
make_http_request_fn_ = std::move(make_http_request_fn);

user_data_ = std::make_unique<UserData>();
auto err = user_data_->Init(file_store_root, test);
return PassError(err);
if (auto err = user_data_->Init(file_store_root, test)) {
return PassError(err);
}

initialized_ = true;
return error::nullerr;
}

bool PsiCash::Initialized() const {
return initialized_;
}

Error PsiCash::Reset(const string& file_store_root, bool test) {
Expand Down Expand Up @@ -598,6 +609,10 @@ Result<Status> PsiCash::RefreshState(
6. If there are still no valid tokens, then things are horribly wrong. Return error.
*/

if (!initialized_) {
return MakeCriticalError("PsiCash is uninitialized");
}

auto auth_tokens = user_data_->GetAuthTokens();
if (auth_tokens.empty()) {
// No tokens.
Expand Down Expand Up @@ -728,8 +743,9 @@ Result<Status> PsiCash::RefreshState(
return RefreshState(purchase_classes, true);
} else if (result->code == kHTTPStatusUnauthorized) {
// This can only happen if the tokens we sent didn't all belong to same user.
// This really should never happen.
user_data_->Clear();
// This really should never happen. We're not checking the return value, as there
// isn't a sane response to a failure at this point.
(void)user_data_->Clear();
return Status::InvalidTokens;
} else if (IsServerError(result->code)) {
return Status::ServerError;
Expand All @@ -743,6 +759,10 @@ Result<PsiCash::NewExpiringPurchaseResponse> PsiCash::NewExpiringPurchase(
const string& transaction_class,
const string& distinguisher,
const int64_t expected_price) {
if (!initialized_) {
return MakeCriticalError("PsiCash is uninitialized");
}

auto result = MakeHTTPRequestWithRetry(
kMethodPOST,
"/transaction",
Expand Down
6 changes: 6 additions & 0 deletions psicash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,18 @@ class PsiCash {
/// filesystem).
/// If `test` is true, then the test server will be used, and other testing interfaces
/// will be available. Should only be used for testing.
/// When uninitialized, data accessors will return zero values, and operations (e.g.,
/// RefreshState and NewExpiringPurchase) will return errors.
error::Error Init(const std::string& user_agent, const std::string& file_store_root,
MakeHTTPRequestFn make_http_request_fn, bool test=false);

/// Resets the PsiCash datastore. Init() must be called after this method is used.
/// Returns an error if the reset failed, likely indicating a filesystem problem.
error::Error Reset(const std::string& file_store_root, bool test=false);

/// Returns true if the library has been successfully initialized (i.e., Init called).
bool Initialized() const;

/// Can be used for updating the HTTP requester function pointer.
void SetHTTPRequestFn(MakeHTTPRequestFn make_http_request_fn);

Expand Down Expand Up @@ -380,6 +385,7 @@ class PsiCash {

protected:
bool test_;
bool initialized_;
std::string user_agent_;
std::string server_scheme_;
std::string server_hostname_;
Expand Down
27 changes: 27 additions & 0 deletions psicash_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,33 @@ TEST_F(TestPsiCash, InitFail) {
}
}

TEST_F(TestPsiCash, UninitializedBehaviour) {
{
// No Init
PsiCashTester pc;
ASSERT_FALSE(pc.Initialized());

ASSERT_EQ(pc.Balance(), 0);

auto res = pc.RefreshState({"speed-boost"});
ASSERT_FALSE(res);
}
{
// Failed Init
auto bad_dir = GetTempDir() + "/a/b/c/d/f/g";
PsiCashTester pc;
auto err = pc.Init(user_agent_, bad_dir.c_str(), nullptr, true);
ASSERT_TRUE(err) << bad_dir;

ASSERT_FALSE(pc.Initialized());

ASSERT_EQ(pc.Balance(), 0);

auto res = pc.RefreshState({"speed-boost"});
ASSERT_FALSE(res);
}
}

TEST_F(TestPsiCash, Clear) {
int64_t want_balance = 123;
auto temp_dir = GetTempDir();
Expand Down

0 comments on commit 88fafa1

Please sign in to comment.