Commit fdecc35f authored by Christos Froussios's avatar Christos Froussios Committed by Commit Bot

[Password Manager] Expand automated tests coverage for export feature

This CL adds tests for:
* Partial write (insufficient disk space to export)
* Export should be offered only if there are passwords
* Export Passwords menu item opens the export dialog.
* The Try Again button restarts the export
* The start and error dialogs are dismissible.

Bug: 815137
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: Ib8d971ac8eda5824ea80c397bd13a26a36a66277
Reviewed-on: https://chromium-review.googlesource.com/934823
Commit-Queue: Christos Froussios <cfroussios@chromium.org>
Reviewed-by: default avatarHector Carmona <hcarmona@chromium.org>
Reviewed-by: default avatarVaclav Brozek <vabr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#539465}
parent 5003e703
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
</div> </div>
<div slot="button-container"> <div slot="button-container">
<paper-button class="secondary-button header-aligned-button" <paper-button class="secondary-button header-aligned-button"
on-click="onCancelButtonTap_"> on-click="onCancelButtonTap_" id="cancelButton">
$i18n{cancel} $i18n{cancel}
</paper-button> </paper-button>
<paper-button class="action-button header-aligned-button" <paper-button class="action-button header-aligned-button"
...@@ -59,11 +59,11 @@ ...@@ -59,11 +59,11 @@
</div> </div>
<div slot="button-container"> <div slot="button-container">
<paper-button class="secondary-button header-aligned-button" <paper-button class="secondary-button header-aligned-button"
on-click="onCancelButtonTap_"> on-click="onCancelButtonTap_" id="cancelErrorButton">
$i18n{cancel} $i18n{cancel}
</paper-button> </paper-button>
<paper-button class="action-button header-aligned-button" <paper-button class="action-button header-aligned-button"
on-click="onExportTap_"> on-click="onExportTap_" id="tryAgainButton">
$i18n{exportPasswordsTryAgain} $i18n{exportPasswordsTryAgain}
</paper-button> </paper-button>
</div> </div>
......
...@@ -606,6 +606,49 @@ TEST_F('SettingsPasswordSectionBrowserTest', 'uiTests', function() { ...@@ -606,6 +606,49 @@ TEST_F('SettingsPasswordSectionBrowserTest', 'uiTests', function() {
done(); done();
}); });
// Chrome offers the export option when there are passwords.
test('offerExportWhenPasswords', function(done) {
const passwordList = [
FakeDataMaker.passwordEntry('googoo.com', 'Larry', 1),
];
const passwordsSection =
createPasswordsSection(passwordManager, passwordList, []);
validatePasswordList(passwordsSection.$.passwordList, passwordList);
assertFalse(passwordsSection.$.menuExportPassword.hidden);
done();
});
// Chrome shouldn't offer the option to export passwords if there are no
// passwords.
test('noExportIfNoPasswords', function(done) {
const passwordList = [];
const passwordsSection =
createPasswordsSection(passwordManager, passwordList, []);
validatePasswordList(passwordsSection.$.passwordList, passwordList);
assertTrue(passwordsSection.$.menuExportPassword.hidden);
done();
});
// Test that clicking the Export Passwords menu item opens the export
// dialog.
test('exportOpen', function(done) {
const passwordList = [
FakeDataMaker.passwordEntry('googoo.com', 'Larry', 1),
];
const passwordsSection =
createPasswordsSection(passwordManager, passwordList, []);
// The export dialog calls requestExportProgressStatus() when opening.
passwordManager.requestExportProgressStatus = (callback) => {
callback(chrome.passwordsPrivate.ExportProgressStatus.NOT_STARTED);
done();
};
passwordManager.addPasswordsFileExportProgressListener = () => {};
MockInteractions.tap(passwordsSection.$.menuExportPassword);
});
// Test that tapping "Export passwords..." notifies the browser accordingly // Test that tapping "Export passwords..." notifies the browser accordingly
test('startExport', function(done) { test('startExport', function(done) {
const exportDialog = createExportPasswordsDialog(passwordManager); const exportDialog = createExportPasswordsDialog(passwordManager);
...@@ -665,12 +708,46 @@ TEST_F('SettingsPasswordSectionBrowserTest', 'uiTests', function() { ...@@ -665,12 +708,46 @@ TEST_F('SettingsPasswordSectionBrowserTest', 'uiTests', function() {
folderName: 'tmp', folderName: 'tmp',
}); });
// Test that the error dialog is shown.
assertTrue(exportDialog.$.dialog_error.open); assertTrue(exportDialog.$.dialog_error.open);
// Test that the error dialog can be dismissed.
MockInteractions.tap(exportDialog.$.cancelErrorButton);
assertFalse(exportDialog.$.dialog_error.open);
done(); done();
mockTimer.uninstall(); mockTimer.uninstall();
}); });
// The error view allows to retry.
test('exportFlowErrorRetry', function(done) {
const exportDialog = createExportPasswordsDialog(passwordManager);
const progressCallback = passwordManager.progressCallback;
// Use this to freeze the delayed progress bar and avoid flakiness.
let mockTimer = new MockTimer();
mockTimer.install();
MockInteractions.tap(exportDialog.$.exportPasswordsButton);
progressCallback(
{status: chrome.passwordsPrivate.ExportProgressStatus.IN_PROGRESS});
progressCallback({
status:
chrome.passwordsPrivate.ExportProgressStatus.FAILED_WRITE_FAILED,
folderName: 'tmp',
});
// Test that the error dialog is shown.
assertTrue(exportDialog.$.dialog_error.open);
// Test that clicking retry will start a new export.
passwordManager.exportPasswords = (callback) => {
callback();
done();
};
MockInteractions.tap(exportDialog.$.tryAgainButton);
mockTimer.uninstall();
});
// Test the export flow. If exporting is slow, Chrome should show the // Test the export flow. If exporting is slow, Chrome should show the
// in-progress dialog for at least 1000ms. // in-progress dialog for at least 1000ms.
test('exportFlowSlow', function(done) { test('exportFlowSlow', function(done) {
...@@ -712,6 +789,18 @@ TEST_F('SettingsPasswordSectionBrowserTest', 'uiTests', function() { ...@@ -712,6 +789,18 @@ TEST_F('SettingsPasswordSectionBrowserTest', 'uiTests', function() {
mockTimer.uninstall(); mockTimer.uninstall();
}); });
// The export dialog is dismissable.
test('exportDismissable', function(done) {
const exportDialog = createExportPasswordsDialog(passwordManager);
assertTrue(exportDialog.$.dialog_start.open);
MockInteractions.tap(exportDialog.$.cancelButton);
assertFalse(exportDialog.$.dialog_start.open);
done();
});
}); });
mocha.run(); mocha.run();
......
...@@ -176,6 +176,29 @@ TEST_F(PasswordManagerExporterTest, WriteFileFailed) { ...@@ -176,6 +176,29 @@ TEST_F(PasswordManagerExporterTest, WriteFileFailed) {
ExportPasswordsResult::WRITE_FAILED, 1); ExportPasswordsResult::WRITE_FAILED, 1);
} }
// A partial write should be considered a failure and be cleaned up.
TEST_F(PasswordManagerExporterTest, WriteFileFailedHalfway) {
const std::string serialised(
password_manager::PasswordCSVWriter::SerializePasswords(password_list_));
const std::string destination_folder_name(
destination_path_.DirName().BaseName().AsUTF8Unsafe());
EXPECT_CALL(mock_write_file_, Run(_, _, _))
.WillOnce(Return(serialised.size() / 2));
EXPECT_CALL(mock_delete_file_, Run(destination_path_, false));
EXPECT_CALL(
mock_on_progress_,
Run(password_manager::ExportProgressStatus::IN_PROGRESS, IsEmpty()));
EXPECT_CALL(mock_on_progress_,
Run(password_manager::ExportProgressStatus::FAILED_WRITE_FAILED,
StrEq(destination_folder_name)));
exporter_.PreparePasswordsForExport();
exporter_.SetDestination(destination_path_);
scoped_task_environment_.RunUntilIdle();
}
// Test that GetProgressStatus() returns the last ExportProgressStatus sent // Test that GetProgressStatus() returns the last ExportProgressStatus sent
// to the callback. // to the callback.
TEST_F(PasswordManagerExporterTest, GetProgressReturnsLastCallbackStatus) { TEST_F(PasswordManagerExporterTest, GetProgressReturnsLastCallbackStatus) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment