blob: fcefeadbc8c405403e820a98177171c5e46e8713 [file] [log] [blame]
// Copyright 2016 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.
#import <EarlGrey/EarlGrey.h>
#import <XCTest/XCTest.h>
#include "base/logging.h"
#include "base/mac/foundation_util.h"
#import "ios/chrome/app/chrome_overlay_window.h"
#import "ios/chrome/app/safe_mode/safe_mode_view_controller.h"
#import "ios/chrome/browser/ui/main/main_view_controller.h"
#include "ios/chrome/grit/ios_chromium_strings.h"
#import "ios/chrome/test/base/scoped_block_swizzler.h"
#import "ios/chrome/test/earl_grey/chrome_test_case.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// Returns the top view controller for rendering the Safe Mode Controller.
UIViewController* GetActiveViewController() {
UIWindow* mainWindow = [[UIApplication sharedApplication] keyWindow];
DCHECK([mainWindow isKindOfClass:[ChromeOverlayWindow class]]);
MainViewController* main_view_controller =
base::mac::ObjCCast<MainViewController>([mainWindow rootViewController]);
return main_view_controller.activeViewController;
}
// Verifies that |message| is displayed.
void AssertMessageOnPage(NSString* message) {
id<GREYMatcher> messageMatcher = [GREYMatchers matcherForText:message];
[[EarlGrey selectElementWithMatcher:messageMatcher]
assertWithMatcher:grey_notNil()];
}
// Verifies that |message| is not displayed.
void AssertMessageNotOnPage(NSString* message) {
id<GREYMatcher> messageMatcher = [GREYMatchers matcherForText:message];
[[EarlGrey selectElementWithMatcher:messageMatcher]
assertWithMatcher:grey_nil()];
}
// Verifies that the button to reload chrome is displayed.
void AssertTryAgainButtonOnPage() {
NSString* tryAgain =
NSLocalizedString(@"IDS_IOS_SAFE_MODE_RELOAD_CHROME", @"");
// This is uppercased to match MDC button label convention.
NSString* tryAgainPrimaryAction =
[tryAgain uppercaseStringWithLocale:[NSLocale currentLocale]];
id<GREYMatcher> tryAgainMatcher =
[GREYMatchers matcherForButtonTitle:tryAgainPrimaryAction];
[[EarlGrey selectElementWithMatcher:tryAgainMatcher]
assertWithMatcher:grey_notNil()];
}
} // namespace
// Expose internal class methods for swizzling.
@interface SafeModeViewController (Testing)
+ (BOOL)detectedThirdPartyMods;
+ (BOOL)hasReportToUpload;
- (NSArray*)startupCrashModules;
@end
// Tests the display of Safe Mode Controller under different error states of
// jailbroken-ness and whether a crash dump was saved.
@interface SafeModeTestCase : ChromeTestCase
@end
@implementation SafeModeTestCase
// Tests that Safe Mode crash upload screen is displayed when there are crash
// reports to upload.
- (void)testSafeModeSendingCrashReport {
// Mocks the +hasReportToUpload method by swizzling to return positively that
// there are crash reports to upload.
ScopedBlockSwizzler hasReport([SafeModeViewController class],
@selector(hasReportToUpload), ^{
return YES;
});
// Instantiates a Safe Mode controller and displays it.
SafeModeViewController* safeModeController =
[[SafeModeViewController alloc] initWithDelegate:nil];
[GetActiveViewController() presentViewController:safeModeController
animated:NO
completion:nil];
// Verifies screen content that shows that crash report is being uploaded.
AssertMessageOnPage(NSLocalizedString(@"IDS_IOS_SAFE_MODE_AW_SNAP", @""));
AssertMessageOnPage(
NSLocalizedString(@"IDS_IOS_SAFE_MODE_UNKNOWN_CAUSE", @""));
AssertTryAgainButtonOnPage();
AssertMessageOnPage(
NSLocalizedString(@"IDS_IOS_SAFE_MODE_SENDING_CRASH_REPORT", @""));
}
// Tests that Safe Mode screen is displayed with a message that there are
// jailbroken mods that caused a crash. Crash reports are not sent.
- (void)testSafeModeDetectedThirdPartyMods {
// Mocks the +detectedThirdPartyMods method by swizzling to return positively
// that device appears to be jailbroken and contains third party mods.
ScopedBlockSwizzler thirdParty([SafeModeViewController class],
@selector(detectedThirdPartyMods), ^{
return YES;
});
// Returns an empty list to simulate no known mods detected.
ScopedBlockSwizzler badModules([SafeModeViewController class],
@selector(startupCrashModules), ^{
return @[];
});
// Instantiates a Safe Mode controller and displays it.
SafeModeViewController* safeModeController =
[[SafeModeViewController alloc] initWithDelegate:nil];
[GetActiveViewController() presentViewController:safeModeController
animated:NO
completion:nil];
// Verifies screen content that does not show crash report being uploaded.
// When devices are jailbroken, the crash reports are not very useful.
AssertMessageOnPage(NSLocalizedString(@"IDS_IOS_SAFE_MODE_AW_SNAP", @""));
AssertMessageOnPage(
NSLocalizedString(@"IDS_IOS_SAFE_MODE_TWEAKS_FOUND", @""));
AssertTryAgainButtonOnPage();
AssertMessageNotOnPage(
NSLocalizedString(@"IDS_IOS_SAFE_MODE_SENDING_CRASH_REPORT", @""));
}
// Tests that Safe Mode screen is displayed with a message that there are
// jailbroken mods listing the names of the known to be bad mods that caused a
// crash. Crash reports are not sent.
- (void)testSafeModeBothThirdPartyModsAndHasReport {
// Mocks the +detectedThirdPartyMods method by swizzling to return positively
// that device appears to be jailbroken and contains third party mods.
ScopedBlockSwizzler thirdParty([SafeModeViewController class],
@selector(detectedThirdPartyMods), ^{
return YES;
});
// Mocked list of bad jailbroken mods. These will be checked later.
NSArray* badModulesList = @[ @"iAmBad", @"MJackson" ];
ScopedBlockSwizzler badModules([SafeModeViewController class],
@selector(startupCrashModules), ^{
return badModulesList;
});
ScopedBlockSwizzler hasReport([SafeModeViewController class],
@selector(hasReportToUpload), ^{
return YES;
});
// Instantiates a Safe Mode controller and displays it.
SafeModeViewController* safeModeController =
[[SafeModeViewController alloc] initWithDelegate:nil];
[GetActiveViewController() presentViewController:safeModeController
animated:NO
completion:nil];
// Verifies screen content that does not show crash report being uploaded.
// When devices are jailbroken, the crash reports are not very useful.
AssertMessageOnPage(NSLocalizedString(@"IDS_IOS_SAFE_MODE_AW_SNAP", @""));
// Constructs the list of bad mods based on |badModulesList| above.
NSString* message =
[NSLocalizedString(@"IDS_IOS_SAFE_MODE_NAMED_TWEAKS_FOUND", @"")
stringByAppendingString:@"\n\n iAmBad\n MJackson"];
AssertMessageOnPage(message);
AssertTryAgainButtonOnPage();
AssertMessageNotOnPage(
NSLocalizedString(@"IDS_IOS_SAFE_MODE_SENDING_CRASH_REPORT", @""));
}
@end