blob: f8d0f168d89fe3840fa7e090d01242715c9e8b1d [file] [log] [blame]
// Copyright 2021 The Chromium OS 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 <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <brillo/file_utils.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "minios/mock_process_manager.h"
#include "minios/mock_recovery_installer.h"
#include "minios/mock_update_engine_proxy.h"
#include "minios/screens.h"
using testing::_;
namespace minios {
namespace {
constexpr char kCrosJsonSnippet[] =
"{\"au\": {\"region_code\": \"au\", \"confirmed\": true, "
"\"description\": \"Australia\", \"keyboards\": [\"xkb:us::eng\"], "
"\"time_zones\": [\"Australia/Sydney\"], \"locales\": [\"en-AU\"], "
"\"keyboard_mechanical_layout\": \"ANSI\", \"regulatory_domain\": "
"\"AU\"}, \"be\": {\"region_code\": \"be\", \"confirmed\": true, "
"\"description\": \"Belgium\", \"keyboards\": [\"xkb:be::nld\", "
"\"xkb:ca:eng:eng\"], \"time_zones\": [\"Europe/Brussels\"], "
"\"locales\": [\"en-GB\"], \"keyboard_mechanical_layout\": \"ISO\", "
"\"regulatory_domain\": \"BE\"}, \"he\": {\"keyboards\": [\"xkbbenld\"]}, "
"\"us\": {\"region_code\": \"us\", \"confirmed\": true, "
"\"description\": \"US\"}}";
} // namespace
class ScreensTest : public ::testing::Test {
public:
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
test_root_ = temp_dir_.GetPath().value();
screens_.SetRootForTest(test_root_);
screens_path_ = base::FilePath(test_root_).Append(kScreens);
base::FilePath locale_dir_en =
base::FilePath(screens_path_).Append("en-US");
ASSERT_TRUE(base::CreateDirectory(locale_dir_en));
base::FilePath locale_dir_fr = base::FilePath(screens_path_).Append("fr");
ASSERT_TRUE(CreateDirectory(locale_dir_fr));
// Create and write constants file.
std::string token_consts =
"TITLE_minios_token_HEIGHT=38 \nDESC_minios_token_HEIGHT=44\n"
"DESC_screen_token_HEIGHT=incorrect\nDEBUG_OPTIONS_BTN_WIDTH=99\n";
ASSERT_TRUE(
base::WriteFile(locale_dir_en.Append("constants.sh"), token_consts));
// Create directories.
ASSERT_TRUE(
base::CreateDirectory(base::FilePath(test_root_).Append("dev/pts")));
console_ = base::FilePath(test_root_).Append("dev/pts/0");
ASSERT_TRUE(base::WriteFile(console_, ""));
ASSERT_TRUE(CreateDirectory(
base::FilePath(screens_path_).Append("glyphs").Append("white")));
ASSERT_TRUE(CreateDirectory(
base::FilePath(test_root_).Append("sys/firmware/vpd/ro")));
ASSERT_TRUE(base::CreateDirectory(
base::FilePath(test_root_).Append("usr/share/misc")));
ASSERT_TRUE(screens_.InitForTest());
}
protected:
// Test directory.
base::ScopedTempDir temp_dir_;
// Path to output pts.
base::FilePath console_;
// Path to /etc/screens in test directory.
base::FilePath screens_path_;
MockProcessManager mock_process_manager_;
Screens screens_{&mock_process_manager_, nullptr, nullptr, nullptr};
std::string test_root_;
};
TEST_F(ScreensTest, UpdateButtons) {
screens_.SetIndexForTest(1);
int menu_items = 4;
bool enter = false;
screens_.UpdateButtons(menu_items, kKeyUp, &enter);
EXPECT_EQ(0, screens_.GetIndexForTest());
// Test range.
screens_.UpdateButtons(menu_items, kKeyUp, &enter);
EXPECT_EQ(0, screens_.GetIndexForTest());
// Move to last item.
screens_.SetIndexForTest(menu_items - 1);
screens_.UpdateButtons(menu_items, kKeyDown, &enter);
EXPECT_EQ(menu_items - 1, screens_.GetIndexForTest());
EXPECT_FALSE(enter);
// Enter key pressed.
screens_.SetIndexForTest(1);
screens_.UpdateButtons(menu_items, kKeyEnter, &enter);
EXPECT_EQ(1, screens_.GetIndexForTest());
EXPECT_TRUE(enter);
// Unknown key, no action taken.
screens_.SetIndexForTest(2);
enter = false;
screens_.UpdateButtons(menu_items, 89, &enter);
EXPECT_EQ(2, screens_.GetIndexForTest());
EXPECT_FALSE(enter);
// If index somehow goes out of range, reset to 0.
screens_.SetIndexForTest(menu_items + 5);
enter = false;
screens_.UpdateButtons(menu_items, kKeyEnter, &enter);
EXPECT_EQ(0, screens_.GetIndexForTest());
}
TEST_F(ScreensTest, UpdateButtonsIsDetachable) {
screens_.SetIndexForTest(1);
bool enter = false;
int menu_items = 4;
screens_.UpdateButtons(menu_items, kKeyVolUp, &enter);
EXPECT_EQ(0, screens_.GetIndexForTest());
// Test range.
screens_.UpdateButtons(menu_items, kKeyVolUp, &enter);
EXPECT_EQ(0, screens_.GetIndexForTest());
// Move to last item.
screens_.SetIndexForTest(menu_items - 1);
screens_.UpdateButtons(menu_items, kKeyVolDown, &enter);
EXPECT_EQ(3, screens_.GetIndexForTest());
EXPECT_FALSE(enter);
// Enter key pressed.
screens_.SetIndexForTest(1);
screens_.UpdateButtons(menu_items, kKeyPower, &enter);
EXPECT_EQ(1, screens_.GetIndexForTest());
EXPECT_TRUE(enter);
}
TEST_F(ScreensTest, MapRegionToKeyboardNoFile) {
std::string keyboard;
EXPECT_FALSE(screens_.MapRegionToKeyboard(&keyboard));
EXPECT_TRUE(keyboard.empty());
}
TEST_F(ScreensTest, MapRegionToKeyboardNotDict) {
std::string not_dict =
"{ au : { region_code : au , confirmed : true, "
" description : Australia , keyboards : [ xkb:us::eng ], "
" time_zones : [ Australia/Sydney ], locales : [ en-AU ], "
" keyboard_mechanical_layout ";
ASSERT_TRUE(base::WriteFile(
base::FilePath(test_root_).Append("usr/share/misc/cros-regions.json"),
not_dict));
std::string keyboard;
EXPECT_FALSE(screens_.MapRegionToKeyboard(&keyboard));
EXPECT_TRUE(keyboard.empty());
}
TEST_F(ScreensTest, MapRegionToKeyboardNoKeyboard) {
ASSERT_TRUE(base::WriteFile(
base::FilePath(test_root_).Append("usr/share/misc/cros-regions.json"),
kCrosJsonSnippet));
// Find keyboard for region. "us" dict entry does not have a keyboard value.
screens_.vpd_region_ = "us";
std::string keyboard;
EXPECT_FALSE(screens_.MapRegionToKeyboard(&keyboard));
EXPECT_TRUE(keyboard.empty());
// Given Vpd region not available at all.
screens_.vpd_region_ = "fr";
EXPECT_FALSE(screens_.MapRegionToKeyboard(&keyboard));
EXPECT_TRUE(keyboard.empty());
}
TEST_F(ScreensTest, MapRegionToKeyboardBadKeyboardFormat) {
ASSERT_TRUE(base::WriteFile(
base::FilePath(test_root_).Append("usr/share/misc/cros-regions.json"),
kCrosJsonSnippet));
// Find keyboard for region. "he" dict entry does not have a correctly
// formatted keyboard value.
screens_.vpd_region_ = "he";
std::string keyboard;
EXPECT_FALSE(screens_.MapRegionToKeyboard(&keyboard));
EXPECT_TRUE(keyboard.empty());
}
TEST_F(ScreensTest, MapRegionToKeyboard) {
ASSERT_TRUE(base::WriteFile(
base::FilePath(test_root_).Append("usr/share/misc/cros-regions.json"),
kCrosJsonSnippet));
// Find keyboard for region.
screens_.vpd_region_ = "au";
std::string keyboard;
EXPECT_TRUE(screens_.MapRegionToKeyboard(&keyboard));
EXPECT_EQ(keyboard, "us");
// Multiple keyboards available.
screens_.vpd_region_ = "be";
EXPECT_TRUE(screens_.MapRegionToKeyboard(&keyboard));
EXPECT_EQ(keyboard, "be");
}
class MockScreens : public Screens {
public:
explicit MockScreens(
std::unique_ptr<MockRecoveryInstaller> mock_recovery_installer,
std::unique_ptr<MockUpdateEngineProxy> mock_update_engine_proxy)
: Screens(nullptr,
std::move(mock_recovery_installer),
nullptr,
std::move(mock_update_engine_proxy)) {}
MOCK_METHOD(bool,
ShowBox,
(int offset_x,
int offset_y,
int size_x,
int size_y,
const std::string& color));
MOCK_METHOD(bool,
ShowImage,
(const base::FilePath& image_name, int offset_x, int offset_y));
MOCK_METHOD(bool,
ShowMessage,
(const std::string& message_token, int offset_x, int offset_y));
MOCK_METHOD(bool,
ShowText,
(const std::string& text,
int glyph_offset_h,
int glyph_offset_v,
const std::string& color));
MOCK_METHOD(void,
ShowInstructionsWithTitle,
(const std::string& message_token));
MOCK_METHOD(void, ShowNewScreen, ());
MOCK_METHOD(void, LanguageMenuOnSelect, ());
MOCK_METHOD(void, GetPassword, ());
MOCK_METHOD(void, LocaleChange, (int LocaleChange));
MOCK_METHOD(void, ShowMiniOsCompleteScreen, ());
MOCK_METHOD(void, UpdateNetworkList, ());
};
class ScreensTestMocks : public ::testing::Test {
public:
ScreensTestMocks()
: mock_recovery_installer_(std::make_unique<MockRecoveryInstaller>()),
mock_recovery_installer_ptr_(mock_recovery_installer_.get()),
mock_update_engine_proxy_(std::make_unique<MockUpdateEngineProxy>()),
mock_update_engine_ptr_(mock_update_engine_proxy_.get()),
mock_screens_(MockScreens(std::move(mock_recovery_installer_),
std::move(mock_update_engine_proxy_))) {}
void SetUp() override {
base::ScopedTempDir temp_dir_;
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
screens_path_ = base::FilePath(temp_dir_.GetPath()).Append(kScreens);
brillo::TouchFile(screens_path_.Append("en-US").Append("constants.sh"));
mock_screens_.SetRootForTest(temp_dir_.GetPath().value());
mock_screens_.InitForTest();
}
protected:
base::FilePath screens_path_;
std::unique_ptr<MockRecoveryInstaller> mock_recovery_installer_;
MockRecoveryInstaller* mock_recovery_installer_ptr_;
std::unique_ptr<MockUpdateEngineProxy> mock_update_engine_proxy_;
MockUpdateEngineProxy* mock_update_engine_ptr_;
MockScreens mock_screens_;
};
TEST_F(ScreensTestMocks, OnKeyPress) {
std::vector<int> keys = {kKeyDown, kKeyEnter, kKeyUp};
mock_screens_.SetIndexForTest(1);
// Index changes up one after both press and release are recorded in
// `key_state_`. `SwitchScreen` is called for every valid key release.
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.OnKeyPress(0, kKeyDown, false);
EXPECT_EQ(mock_screens_.GetIndexForTest(), 1);
mock_screens_.OnKeyPress(0, kKeyDown, true);
EXPECT_EQ(mock_screens_.GetIndexForTest(), 2);
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.OnKeyPress(0, kKeyEnter, false);
mock_screens_.OnKeyPress(0, kKeyEnter, true);
}
TEST_F(ScreensTestMocks, ScreenFlowLanguage) {
// Test making a selection on the language screen and then returning back to
// the previous screen.
// Index 0 on a normal screen is the language dropdown button.
mock_screens_.SetIndexForTest(0);
mock_screens_.SetScreenForTest(ScreenType::kWelcomeScreen);
// Calls language menu.
EXPECT_CALL(mock_screens_, LanguageMenuOnSelect());
mock_screens_.SwitchScreen(true);
EXPECT_EQ(ScreenType::kLanguageDropDownScreen,
mock_screens_.GetScreenForTest());
// Select language from menu, make changes, and return to previous screen.
EXPECT_CALL(mock_screens_, LocaleChange(_));
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.SwitchScreen(true);
EXPECT_EQ(ScreenType::kWelcomeScreen, mock_screens_.GetScreenForTest());
}
TEST_F(ScreensTestMocks, ScreenFlowForwardWithNetwork) {
// Test the screen flow forward starting from the welcome screen.
mock_screens_.SetIndexForTest(1);
mock_screens_.SetScreenForTest(ScreenType::kWelcomeScreen);
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.SwitchScreen(/*enter=*/false);
// Screen has not changed since enter is false.
EXPECT_EQ(ScreenType::kWelcomeScreen, mock_screens_.GetScreenForTest());
// Moves to next screen in flow. kNetworkDropDownScreen.
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.SwitchScreen(true);
EXPECT_EQ(ScreenType::kNetworkDropDownScreen,
mock_screens_.GetScreenForTest());
// Enter goes to kExpandedNetworkDropDownScreen.
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.SwitchScreen(true);
EXPECT_EQ(ScreenType::kExpandedNetworkDropDownScreen,
mock_screens_.GetScreenForTest());
// Enter goes to kPasswordScreen.
mock_screens_.SetIndexForTest(1);
mock_screens_.SetNetworkListForTest_({"test1", "test2"});
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.SwitchScreen(true);
EXPECT_EQ(ScreenType::kPasswordScreen, mock_screens_.GetScreenForTest());
}
TEST_F(ScreensTestMocks, ScreenBackward) {
// Test the screen flow backward starting from the password screen.
mock_screens_.SetIndexForTest(2);
// Start at password screen.
mock_screens_.SetScreenForTest(ScreenType::kPasswordScreen);
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.SwitchScreen(true);
// Moves back to kDropDownScreen.
EXPECT_EQ(ScreenType::kNetworkDropDownScreen,
mock_screens_.GetScreenForTest());
// Enter goes back to kWelcomeScreen.
mock_screens_.SetIndexForTest(2);
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.SwitchScreen(true);
EXPECT_EQ(ScreenType::kWelcomeScreen, mock_screens_.GetScreenForTest());
// Cannot go further back from kWelcomeScreen.
mock_screens_.SetIndexForTest(2);
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.SwitchScreen(true);
EXPECT_EQ(ScreenType::kWelcomeScreen, mock_screens_.GetScreenForTest());
}
TEST_F(ScreensTestMocks, UpdateEngineError) {
mock_screens_.display_update_engine_state_ = true;
update_engine::StatusResult status;
status.set_current_operation(update_engine::Operation::ERROR);
// Show download error.
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.OnProgressChanged(status);
EXPECT_FALSE(mock_screens_.display_update_engine_state_);
}
TEST_F(ScreensTestMocks, UpdateEngineProgressComplete) {
mock_screens_.display_update_engine_state_ = true;
update_engine::StatusResult status;
status.set_current_operation(update_engine::Operation::UPDATED_NEED_REBOOT);
EXPECT_CALL(mock_screens_, ShowMiniOsCompleteScreen());
mock_screens_.OnProgressChanged(status);
// Freeze UI, nothing left to do but reboot.
EXPECT_FALSE(mock_screens_.display_update_engine_state_);
}
TEST_F(ScreensTestMocks, IdleError) {
mock_screens_.display_update_engine_state_ = true;
update_engine::StatusResult status;
status.set_current_operation(update_engine::Operation::FINALIZING);
mock_screens_.OnProgressChanged(status);
// If it changes to `IDLE` from an incorrect state it is an error.
status.set_current_operation(update_engine::Operation::IDLE);
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.OnProgressChanged(status);
EXPECT_FALSE(mock_screens_.display_update_engine_state_);
}
TEST_F(ScreensTestMocks, InvalidNetwork) {
mock_screens_.SetScreenForTest(ScreenType::kExpandedNetworkDropDownScreen);
// Set list of available networks to empty.
mock_screens_.SetNetworkListForTest_({"network"});
mock_screens_.SetIndexForTest(1);
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.SwitchScreen(true);
// Goes back to the dropdown screen because the network chosen was invalid.
EXPECT_EQ(ScreenType::kExpandedNetworkDropDownScreen,
mock_screens_.GetScreenForTest());
mock_screens_.SetNetworkListForTest_({"test1"});
mock_screens_.SetIndexForTest(5);
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.SwitchScreen(true);
// Goes back to the dropdown screen because the network chosen was invalid.
EXPECT_EQ(ScreenType::kExpandedNetworkDropDownScreen,
mock_screens_.GetScreenForTest());
}
TEST_F(ScreensTestMocks, RestartFromDownloadError) {
// Starting from Download error screen.
mock_screens_.SetScreenForTest(ScreenType::kDownloadError);
mock_screens_.SetIndexForTest(1);
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.SwitchScreen(true);
// Back to start screen.
EXPECT_EQ(ScreenType::kWelcomeScreen, mock_screens_.GetScreenForTest());
}
TEST_F(ScreensTestMocks, RestartFromNetworkError) {
// Starting from network error screen.
mock_screens_.SetScreenForTest(ScreenType::kNetworkError);
mock_screens_.SetIndexForTest(1);
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.SwitchScreen(true);
// Back to dropdown.
EXPECT_EQ(ScreenType::kNetworkDropDownScreen,
mock_screens_.GetScreenForTest());
}
TEST_F(ScreensTestMocks, GetNetworks) {
mock_screens_.OnGetNetworks({"test1", "test2", "test3"}, nullptr);
// Menu count is updated.
EXPECT_EQ(
4, mock_screens_.menu_count_[ScreenType::kExpandedNetworkDropDownScreen]);
// Network error.
brillo::ErrorPtr error_ptr =
brillo::Error::Create(FROM_HERE, "HTTP", "404", "Not found", nullptr);
EXPECT_CALL(mock_screens_, ShowNewScreen());
// Reset and show error screen.
mock_screens_.OnGetNetworks({}, error_ptr.get());
// One in the menu count for the back button.
EXPECT_EQ(
1, mock_screens_.menu_count_[ScreenType::kExpandedNetworkDropDownScreen]);
EXPECT_EQ(0, mock_screens_.network_list_.size());
EXPECT_EQ(ScreenType::kNetworkError, mock_screens_.GetScreenForTest());
}
TEST_F(ScreensTestMocks, GetNetworksRefresh) {
mock_screens_.SetScreenForTest(ScreenType::kExpandedNetworkDropDownScreen);
EXPECT_TRUE(mock_screens_.network_list_.empty());
// Menu count is updated amd drop down screen is refreshed.
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.OnGetNetworks({"test1", "test2", "test3"}, nullptr);
EXPECT_EQ(
4, mock_screens_.menu_count_[ScreenType::kExpandedNetworkDropDownScreen]);
}
TEST_F(ScreensTestMocks, OnConnectError) {
mock_screens_.chosen_network_ = "test-ssid";
// Network error, show corresponding screen.
brillo::ErrorPtr error_ptr =
brillo::Error::Create(FROM_HERE, "HTTP", "404", "Not found", nullptr);
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.OnConnect(mock_screens_.chosen_network_, error_ptr.get());
EXPECT_EQ(ScreenType::kConnectionError, mock_screens_.GetScreenForTest());
EXPECT_TRUE(mock_screens_.chosen_network_.empty());
}
TEST_F(ScreensTestMocks, OnPasswordError) {
mock_screens_.chosen_network_ = "test-ssid";
// Network error, show corresponding screen.
brillo::ErrorPtr error_ptr = brillo::Error::Create(
FROM_HERE, "Password", "org.chromium.flimflam.Error.InvalidPassphrase",
"Invalid passphrase", nullptr);
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.OnConnect(mock_screens_.chosen_network_, error_ptr.get());
EXPECT_EQ(ScreenType::kPasswordError, mock_screens_.GetScreenForTest());
EXPECT_TRUE(mock_screens_.chosen_network_.empty());
}
TEST_F(ScreensTestMocks, ChangeErrorScreen) {
mock_screens_.SetScreenForTest(ScreenType::kNetworkDropDownScreen);
mock_screens_.SetIndexForTest(2);
mock_screens_.display_update_engine_state_ = true;
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.ChangeToErrorScreen(ScreenType::kNetworkError);
// Reset state and show error.
EXPECT_EQ(ScreenType::kNetworkError, mock_screens_.GetScreenForTest());
EXPECT_EQ(1, mock_screens_.GetIndexForTest());
EXPECT_FALSE(mock_screens_.display_update_engine_state_);
}
TEST_F(ScreensTestMocks, ErrorScreenFallBack) {
// Error images not available, fall back to general error screen.
brillo::TouchFile(
screens_path_.Append("en-US").Append("title_MiniOS_test_error.png"));
EXPECT_CALL(mock_screens_, ShowInstructionsWithTitle("MiniOS_general_error"));
mock_screens_.ShowErrorScreen("MiniOS_test_error");
// Create both error images to show error.
brillo::TouchFile(
screens_path_.Append("en-US").Append("desc_MiniOS_test_error.png"));
EXPECT_CALL(mock_screens_, ShowInstructionsWithTitle("MiniOS_test_error"));
mock_screens_.ShowErrorScreen("MiniOS_test_error");
}
TEST_F(ScreensTestMocks, RepartitionDisk) {
EXPECT_CALL(mock_screens_, ShowNewScreen());
EXPECT_CALL(*mock_recovery_installer_ptr_, RepartitionDisk())
.WillOnce(testing::Return(true));
mock_screens_.OnUserPermission();
}
TEST_F(ScreensTestMocks, RepartitionDiskFailed) {
// Show error screen on repartition failure.
EXPECT_CALL(mock_screens_, ShowNewScreen());
EXPECT_CALL(*mock_recovery_installer_ptr_, RepartitionDisk())
.WillOnce(testing::Return(false));
mock_screens_.OnUserPermission();
EXPECT_EQ(ScreenType::kGeneralError, mock_screens_.GetScreenForTest());
}
TEST_F(ScreensTestMocks, ErrorScreenIntoDebugOptionsScreen) {
for (const auto& screen_type :
{ScreenType::kDownloadError, ScreenType::kNetworkError,
ScreenType::kPasswordError, ScreenType::kConnectionError}) {
mock_screens_.SetScreenForTest(screen_type);
mock_screens_.SetIndexForTest(2);
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.SwitchScreen(true);
EXPECT_EQ(ScreenType::kDebugOptionsScreen,
mock_screens_.GetScreenForTest());
}
}
TEST_F(ScreensTestMocks, DebugOptionsScreenBackGoesToWelcome) {
mock_screens_.SetScreenForTest(ScreenType::kDebugOptionsScreen);
mock_screens_.SetIndexForTest(2);
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.SwitchScreen(true);
EXPECT_EQ(ScreenType::kWelcomeScreen, mock_screens_.GetScreenForTest());
}
TEST_F(ScreensTestMocks, DebugOptionsScreenIntoLogScreen) {
mock_screens_.SetScreenForTest(ScreenType::kDebugOptionsScreen);
mock_screens_.SetIndexForTest(1);
EXPECT_CALL(mock_screens_, ShowNewScreen());
mock_screens_.SwitchScreen(true);
EXPECT_EQ(ScreenType::kLogScreen, mock_screens_.GetScreenForTest());
}
TEST_F(ScreensTestMocks, LogScreenNoScreenRefresh) {
base::ScopedTempDir tmp_dir_;
ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir());
const base::FilePath& kPath = tmp_dir_.GetPath().Append("file");
ASSERT_TRUE(base::WriteFile(kPath, "a\nb\nc\n"));
mock_screens_.log_path_ = kPath;
// No redraw as already on the correct screen.
mock_screens_.SetScreenForTest(ScreenType::kLogScreen);
mock_screens_.SetIndexForTest(1);
mock_screens_.SwitchScreen(true);
EXPECT_EQ(ScreenType::kLogScreen, mock_screens_.GetScreenForTest());
}
TEST_F(ScreensTestMocks, LogScreenPageDownAndUps) {
base::ScopedTempDir tmp_dir_;
ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir());
const base::FilePath& kPath = tmp_dir_.GetPath().Append("file");
ASSERT_TRUE(base::WriteFile(kPath, "a\nb\nc\n"));
mock_screens_.log_path_ = kPath;
mock_screens_.log_offset_idx_ = 0;
mock_screens_.log_offsets_ = {0, 3, 5};
// Act of scrolling up on the log.
mock_screens_.SetScreenForTest(ScreenType::kLogScreen);
mock_screens_.SetIndexForTest(1);
// No redraws should be triggered.
mock_screens_.SwitchScreen(true);
EXPECT_EQ(ScreenType::kLogScreen, mock_screens_.GetScreenForTest());
// Act of scrolling down on the log.
mock_screens_.SetIndexForTest(2);
EXPECT_CALL(
mock_screens_,
ShowImage(screens_path_.Append("log_area_border_large.png"), _, _));
EXPECT_CALL(mock_screens_, ShowText("\nc", _, _, "white"));
mock_screens_.SwitchScreen(true);
EXPECT_EQ(ScreenType::kLogScreen, mock_screens_.GetScreenForTest());
// Act of scrolling up on the log.
mock_screens_.SetIndexForTest(1);
EXPECT_CALL(
mock_screens_,
ShowImage(screens_path_.Append("log_area_border_large.png"), _, _));
EXPECT_CALL(mock_screens_, ShowText("a\nb", _, _, "white"));
mock_screens_.SwitchScreen(true);
EXPECT_EQ(ScreenType::kLogScreen, mock_screens_.GetScreenForTest());
}
TEST_F(ScreensTestMocks, LogScreenNonEnter) {
mock_screens_.SetScreenForTest(ScreenType::kLogScreen);
mock_screens_.SetIndexForTest(1);
mock_screens_.SwitchScreen(false);
EXPECT_EQ(ScreenType::kLogScreen, mock_screens_.GetScreenForTest());
}
TEST_F(ScreensTestMocks, StartUpdateFailed) {
// Show error screen on update engine failure.
EXPECT_CALL(mock_screens_, ShowNewScreen());
EXPECT_CALL(*mock_recovery_installer_ptr_, RepartitionDisk())
.WillOnce(testing::Return(true));
EXPECT_CALL(*mock_update_engine_ptr_, StartUpdate())
.WillOnce(testing::Return(false));
mock_screens_.OnUserPermission();
EXPECT_EQ(ScreenType::kDownloadError, mock_screens_.GetScreenForTest());
}
} // namespace minios