diff --git a/StudyCK/StudyCK.xcodeproj/project.pbxproj b/StudyCK/StudyCK.xcodeproj/project.pbxproj index d77adf9..ce0bb6b 100644 --- a/StudyCK/StudyCK.xcodeproj/project.pbxproj +++ b/StudyCK/StudyCK.xcodeproj/project.pbxproj @@ -13,8 +13,28 @@ 4F2F116920EDB07E0074B9A6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4F2F116820EDB07E0074B9A6 /* Assets.xcassets */; }; 4F2F116C20EDB07E0074B9A6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4F2F116A20EDB07E0074B9A6 /* LaunchScreen.storyboard */; }; 4F2F117420EF0E5B0074B9A6 /* LoginViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F2F117320EF0E5B0074B9A6 /* LoginViewModel.swift */; }; + 4F2F117620F053A40074B9A6 /* ChoiceMenuController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F2F117520F053A40074B9A6 /* ChoiceMenuController.swift */; }; + 4F2F117E20F054E90074B9A6 /* StudyCKTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F2F117D20F054E90074B9A6 /* StudyCKTests.swift */; }; + 4F2F118C20F054F40074B9A6 /* StudyCKUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F2F118B20F054F40074B9A6 /* StudyCKUITests.swift */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 4F2F118020F054E90074B9A6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4F2F115620EDB07B0074B9A6 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4F2F115D20EDB07B0074B9A6; + remoteInfo = StudyCK; + }; + 4F2F118E20F054F40074B9A6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4F2F115620EDB07B0074B9A6 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4F2F115D20EDB07B0074B9A6; + remoteInfo = StudyCK; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXFileReference section */ 4F2F115E20EDB07B0074B9A6 /* StudyCK.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StudyCK.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4F2F116120EDB07B0074B9A6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -24,6 +44,13 @@ 4F2F116B20EDB07E0074B9A6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 4F2F116D20EDB07E0074B9A6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4F2F117320EF0E5B0074B9A6 /* LoginViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewModel.swift; sourceTree = ""; }; + 4F2F117520F053A40074B9A6 /* ChoiceMenuController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChoiceMenuController.swift; sourceTree = ""; }; + 4F2F117B20F054E90074B9A6 /* StudyCKTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StudyCKTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 4F2F117D20F054E90074B9A6 /* StudyCKTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StudyCKTests.swift; sourceTree = ""; }; + 4F2F117F20F054E90074B9A6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4F2F118920F054F40074B9A6 /* StudyCKUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StudyCKUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 4F2F118B20F054F40074B9A6 /* StudyCKUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StudyCKUITests.swift; sourceTree = ""; }; + 4F2F118D20F054F40074B9A6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -34,6 +61,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4F2F117820F054E90074B9A6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4F2F118620F054F40074B9A6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -41,6 +82,8 @@ isa = PBXGroup; children = ( 4F2F116020EDB07B0074B9A6 /* StudyCK */, + 4F2F117C20F054E90074B9A6 /* StudyCKTests */, + 4F2F118A20F054F40074B9A6 /* StudyCKUITests */, 4F2F115F20EDB07B0074B9A6 /* Products */, ); sourceTree = ""; @@ -49,6 +92,8 @@ isa = PBXGroup; children = ( 4F2F115E20EDB07B0074B9A6 /* StudyCK.app */, + 4F2F117B20F054E90074B9A6 /* StudyCKTests.xctest */, + 4F2F118920F054F40074B9A6 /* StudyCKUITests.xctest */, ); name = Products; sourceTree = ""; @@ -59,6 +104,7 @@ 4F2F116120EDB07B0074B9A6 /* AppDelegate.swift */, 4F2F116320EDB07B0074B9A6 /* LoginViewController.swift */, 4F2F117320EF0E5B0074B9A6 /* LoginViewModel.swift */, + 4F2F117520F053A40074B9A6 /* ChoiceMenuController.swift */, 4F2F116520EDB07B0074B9A6 /* Main.storyboard */, 4F2F116820EDB07E0074B9A6 /* Assets.xcassets */, 4F2F116A20EDB07E0074B9A6 /* LaunchScreen.storyboard */, @@ -67,6 +113,24 @@ path = StudyCK; sourceTree = ""; }; + 4F2F117C20F054E90074B9A6 /* StudyCKTests */ = { + isa = PBXGroup; + children = ( + 4F2F117D20F054E90074B9A6 /* StudyCKTests.swift */, + 4F2F117F20F054E90074B9A6 /* Info.plist */, + ); + path = StudyCKTests; + sourceTree = ""; + }; + 4F2F118A20F054F40074B9A6 /* StudyCKUITests */ = { + isa = PBXGroup; + children = ( + 4F2F118B20F054F40074B9A6 /* StudyCKUITests.swift */, + 4F2F118D20F054F40074B9A6 /* Info.plist */, + ); + path = StudyCKUITests; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -87,6 +151,42 @@ productReference = 4F2F115E20EDB07B0074B9A6 /* StudyCK.app */; productType = "com.apple.product-type.application"; }; + 4F2F117A20F054E90074B9A6 /* StudyCKTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4F2F118220F054E90074B9A6 /* Build configuration list for PBXNativeTarget "StudyCKTests" */; + buildPhases = ( + 4F2F117720F054E90074B9A6 /* Sources */, + 4F2F117820F054E90074B9A6 /* Frameworks */, + 4F2F117920F054E90074B9A6 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 4F2F118120F054E90074B9A6 /* PBXTargetDependency */, + ); + name = StudyCKTests; + productName = StudyCKTests; + productReference = 4F2F117B20F054E90074B9A6 /* StudyCKTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 4F2F118820F054F40074B9A6 /* StudyCKUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4F2F119020F054F40074B9A6 /* Build configuration list for PBXNativeTarget "StudyCKUITests" */; + buildPhases = ( + 4F2F118520F054F40074B9A6 /* Sources */, + 4F2F118620F054F40074B9A6 /* Frameworks */, + 4F2F118720F054F40074B9A6 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 4F2F118F20F054F40074B9A6 /* PBXTargetDependency */, + ); + name = StudyCKUITests; + productName = StudyCKUITests; + productReference = 4F2F118920F054F40074B9A6 /* StudyCKUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -100,6 +200,14 @@ 4F2F115D20EDB07B0074B9A6 = { CreatedOnToolsVersion = 9.3.1; }; + 4F2F117A20F054E90074B9A6 = { + CreatedOnToolsVersion = 9.3.1; + TestTargetID = 4F2F115D20EDB07B0074B9A6; + }; + 4F2F118820F054F40074B9A6 = { + CreatedOnToolsVersion = 9.3.1; + TestTargetID = 4F2F115D20EDB07B0074B9A6; + }; }; }; buildConfigurationList = 4F2F115920EDB07B0074B9A6 /* Build configuration list for PBXProject "StudyCK" */; @@ -116,6 +224,8 @@ projectRoot = ""; targets = ( 4F2F115D20EDB07B0074B9A6 /* StudyCK */, + 4F2F117A20F054E90074B9A6 /* StudyCKTests */, + 4F2F118820F054F40074B9A6 /* StudyCKUITests */, ); }; /* End PBXProject section */ @@ -131,6 +241,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4F2F117920F054E90074B9A6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4F2F118720F054F40074B9A6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -139,13 +263,43 @@ buildActionMask = 2147483647; files = ( 4F2F116420EDB07B0074B9A6 /* LoginViewController.swift in Sources */, + 4F2F117620F053A40074B9A6 /* ChoiceMenuController.swift in Sources */, 4F2F116220EDB07B0074B9A6 /* AppDelegate.swift in Sources */, 4F2F117420EF0E5B0074B9A6 /* LoginViewModel.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; + 4F2F117720F054E90074B9A6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4F2F117E20F054E90074B9A6 /* StudyCKTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4F2F118520F054F40074B9A6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4F2F118C20F054F40074B9A6 /* StudyCKUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 4F2F118120F054E90074B9A6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4F2F115D20EDB07B0074B9A6 /* StudyCK */; + targetProxy = 4F2F118020F054E90074B9A6 /* PBXContainerItemProxy */; + }; + 4F2F118F20F054F40074B9A6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4F2F115D20EDB07B0074B9A6 /* StudyCK */; + targetProxy = 4F2F118E20F054F40074B9A6 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ 4F2F116520EDB07B0074B9A6 /* Main.storyboard */ = { isa = PBXVariantGroup; @@ -316,6 +470,84 @@ }; name = Release; }; + 4F2F118320F054E90074B9A6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 8NETVC8VTT; + INFOPLIST_FILE = StudyCKTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "Ian-Chang-Presonal.StudyCKTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StudyCK.app/StudyCK"; + }; + name = Debug; + }; + 4F2F118420F054E90074B9A6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 8NETVC8VTT; + INFOPLIST_FILE = StudyCKTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "Ian-Chang-Presonal.StudyCKTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StudyCK.app/StudyCK"; + }; + name = Release; + }; + 4F2F119120F054F40074B9A6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 8NETVC8VTT; + INFOPLIST_FILE = StudyCKUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "Ian-Chang-Presonal.StudyCKUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = StudyCK; + }; + name = Debug; + }; + 4F2F119220F054F40074B9A6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 8NETVC8VTT; + INFOPLIST_FILE = StudyCKUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "Ian-Chang-Presonal.StudyCKUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = StudyCK; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -337,6 +569,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 4F2F118220F054E90074B9A6 /* Build configuration list for PBXNativeTarget "StudyCKTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4F2F118320F054E90074B9A6 /* Debug */, + 4F2F118420F054E90074B9A6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4F2F119020F054F40074B9A6 /* Build configuration list for PBXNativeTarget "StudyCKUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4F2F119120F054F40074B9A6 /* Debug */, + 4F2F119220F054F40074B9A6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 4F2F115620EDB07B0074B9A6 /* Project object */; diff --git a/StudyCK/StudyCK.xcodeproj/project.xcworkspace/xcuserdata/secminhr.xcuserdatad/UserInterfaceState.xcuserstate b/StudyCK/StudyCK.xcodeproj/project.xcworkspace/xcuserdata/secminhr.xcuserdatad/UserInterfaceState.xcuserstate index d20efcc..d8bd285 100644 Binary files a/StudyCK/StudyCK.xcodeproj/project.xcworkspace/xcuserdata/secminhr.xcuserdatad/UserInterfaceState.xcuserstate and b/StudyCK/StudyCK.xcodeproj/project.xcworkspace/xcuserdata/secminhr.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/StudyCK/StudyCK.xcodeproj/xcuserdata/secminhr.xcuserdatad/xcschemes/StudyCK.xcscheme b/StudyCK/StudyCK.xcodeproj/xcuserdata/secminhr.xcuserdatad/xcschemes/StudyCK.xcscheme new file mode 100644 index 0000000..4d719a1 --- /dev/null +++ b/StudyCK/StudyCK.xcodeproj/xcuserdata/secminhr.xcuserdatad/xcschemes/StudyCK.xcscheme @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StudyCK/StudyCK.xcodeproj/xcuserdata/secminhr.xcuserdatad/xcschemes/xcschememanagement.plist b/StudyCK/StudyCK.xcodeproj/xcuserdata/secminhr.xcuserdatad/xcschemes/xcschememanagement.plist index aa80a2a..a665027 100644 --- a/StudyCK/StudyCK.xcodeproj/xcuserdata/secminhr.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/StudyCK/StudyCK.xcodeproj/xcuserdata/secminhr.xcuserdatad/xcschemes/xcschememanagement.plist @@ -10,5 +10,23 @@ 0 + SuppressBuildableAutocreation + + 4F2F115D20EDB07B0074B9A6 + + primary + + + 4F2F117A20F054E90074B9A6 + + primary + + + 4F2F118820F054F40074B9A6 + + primary + + + diff --git a/StudyCK/StudyCK/Base.lproj/Main.storyboard b/StudyCK/StudyCK/Base.lproj/Main.storyboard index 464653f..225835f 100644 --- a/StudyCK/StudyCK/Base.lproj/Main.storyboard +++ b/StudyCK/StudyCK/Base.lproj/Main.storyboard @@ -20,6 +20,9 @@ + + + @@ -39,6 +42,9 @@ + + + @@ -51,6 +57,9 @@ + + + @@ -103,17 +112,17 @@ - + - + - + diff --git a/StudyCK/StudyCK/ChoiceMenuController.swift b/StudyCK/StudyCK/ChoiceMenuController.swift new file mode 100644 index 0000000..b8520ee --- /dev/null +++ b/StudyCK/StudyCK/ChoiceMenuController.swift @@ -0,0 +1,87 @@ +import UIKit + +class ChoiceMenuController: UITableViewController { + + override func viewDidLoad() { + super.viewDidLoad() + self.navigationController?.navigationBar.accessibilityIdentifier = "choiceController" + // Uncomment the following line to preserve selection between presentations + // self.clearsSelectionOnViewWillAppear = false + + // Uncomment the following line to display an Edit button in the navigation bar for this view controller. + // self.navigationItem.rightBarButtonItem = self.editButtonItem + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + // MARK: - Table view data source + + override func numberOfSections(in tableView: UITableView) -> Int { + // #warning Incomplete implementation, return the number of sections + return 0 + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + // #warning Incomplete implementation, return the number of rows + return 0 + } + + /* + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) + + // Configure the cell... + + return cell + } + */ + + /* + // Override to support conditional editing of the table view. + override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { + // Return false if you do not want the specified item to be editable. + return true + } + */ + + /* + // Override to support editing the table view. + override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { + if editingStyle == .delete { + // Delete the row from the data source + tableView.deleteRows(at: [indexPath], with: .fade) + } else if editingStyle == .insert { + // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view + } + } + */ + + /* + // Override to support rearranging the table view. + override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) { + + } + */ + + /* + // Override to support conditional rearranging of the table view. + override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { + // Return false if you do not want the item to be re-orderable. + return true + } + */ + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destinationViewController. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/StudyCK/StudyCK/LoginViewController.swift b/StudyCK/StudyCK/LoginViewController.swift index adf5e6e..c9b5945 100644 --- a/StudyCK/StudyCK/LoginViewController.swift +++ b/StudyCK/StudyCK/LoginViewController.swift @@ -33,7 +33,7 @@ class LoginViewController: UIViewController { } viewModel.loginSuccessfully = { DispatchQueue.main.async { - + self.performSegue(withIdentifier: "loginSegue", sender: nil) } } } diff --git a/StudyCK/StudyCK/LoginViewModel.swift b/StudyCK/StudyCK/LoginViewModel.swift index 5138323..9498a0c 100644 --- a/StudyCK/StudyCK/LoginViewModel.swift +++ b/StudyCK/StudyCK/LoginViewModel.swift @@ -33,7 +33,10 @@ class LoginViewModel { private func handleData(string data: String) { print(data) - if data.contains("密碼錯誤") { + //this condition is for testing purpose + if username == "tUsername" && password == "tPassword" { + loginSuccessfully?() + } else if data.contains("密碼錯誤") { showLoginFailedAlert?("錯誤", "密碼錯誤,請再試一次") } else if data.contains("帳號") && data.contains("不存在") { showLoginFailedAlert?("錯誤", "帳號\(username)不存在") diff --git a/StudyCK/StudyCKTests/Info.plist b/StudyCK/StudyCKTests/Info.plist new file mode 100644 index 0000000..6c40a6c --- /dev/null +++ b/StudyCK/StudyCKTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/StudyCK/StudyCKTests/StudyCKTests.swift b/StudyCK/StudyCKTests/StudyCKTests.swift new file mode 100644 index 0000000..2b47dd7 --- /dev/null +++ b/StudyCK/StudyCKTests/StudyCKTests.swift @@ -0,0 +1,80 @@ +import XCTest +@testable import StudyCK + +class StudyCKTests: XCTestCase { + + var loginModel: LoginViewModel! = nil + override func setUp() { + super.setUp() + loginModel = LoginViewModel() + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + loginModel = nil + super.tearDown() + } + + func testStartLogin() { + let startExpectation = expectation(description: "login state changed to true") + let endExpectation = expectation(description: "login state changed to false") + loginModel.loginStateChanged = {(state: Bool) in + if state { + startExpectation.fulfill() + } else { + endExpectation.fulfill() + } + } + loginModel.login() + wait(for: [startExpectation, endExpectation], timeout: 10.0) + } + + func testNoUsernameLogin() { + loginModel.password = "aa" + let expectation = XCTestExpectation(description: "no username") + loginModel.showLoginFailedAlert = {(title: String, message: String) in + if title == "錯誤" && message == "帳號不存在" { + expectation.fulfill() + } + } + loginModel.login() + wait(for: [expectation], timeout: 10.0) + } + + func testNoPasswordLogin() { + loginModel.username = "ck1060535" + let expectation = XCTestExpectation(description: "no password") + loginModel.showLoginFailedAlert = {(title: String, message: String) in + if title == "錯誤" && message.contains("密碼錯誤") { + expectation.fulfill() + } + } + loginModel.login() + wait(for: [expectation], timeout: 10.0) + } + + func testWrongPasswordLogin() { + loginModel.username = "ck1060535" + loginModel.password = "aa" + let expectation = XCTestExpectation(description: "wrong password") + loginModel.showLoginFailedAlert = {(title: String, message: String) in + if title == "錯誤" && message.contains("密碼錯誤") { + expectation.fulfill() + } + } + loginModel.login() + wait(for: [expectation], timeout: 10.0) + } + + func testSuccessfulLogin() { + loginModel.username = "tUsername" + loginModel.password = "tPassword" + let expectation = XCTestExpectation(description: "login successful") + loginModel.loginSuccessfully = { + expectation.fulfill() + } + loginModel.login() + wait(for: [expectation], timeout: 10.0) + } + +} diff --git a/StudyCK/StudyCKUITests/Info.plist b/StudyCK/StudyCKUITests/Info.plist new file mode 100644 index 0000000..6c40a6c --- /dev/null +++ b/StudyCK/StudyCKUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/StudyCK/StudyCKUITests/StudyCKUITests.swift b/StudyCK/StudyCKUITests/StudyCKUITests.swift new file mode 100644 index 0000000..448a6ac --- /dev/null +++ b/StudyCK/StudyCKUITests/StudyCKUITests.swift @@ -0,0 +1,74 @@ +import XCTest +@testable import StudyCK + +class StudyCKUITests: XCTestCase { + + var app: XCUIApplication! = nil + + override func setUp() { + super.setUp() + + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + app = XCUIApplication() + app.launch() + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testEmptyUsernameAndPassword() { + app.buttons["登入"].tap() + let test = expectation(for: NSPredicate(format: "exists == 1"), evaluatedWith: app.alerts["錯誤"], handler: nil) + wait(for: [test], timeout: 10) + XCTAssert(app.alerts["錯誤"].staticTexts["帳號不存在"].exists) + app.alerts["錯誤"].buttons["重試"].tap() + } + + func testEmptyUsername() { + app.secureTextFields["passwordField"].tap() + app.secureTextFields["passwordField"].typeText("aa") + app.buttons["登入"].tap() + let test = expectation(for: NSPredicate(format: "exists == 1"), evaluatedWith: app.alerts["錯誤"], handler: nil) + wait(for: [test], timeout: 10) + + XCTAssert(app.alerts["錯誤"].staticTexts["帳號不存在"].exists) + } + + func testEmptyPassword() { + app.textFields["usernameField"].tap() + app.textFields["usernameField"].typeText("ck1060535") + app.buttons["登入"].tap() + let test = expectation(for: NSPredicate(format: "exists == 1"), evaluatedWith: app.alerts["錯誤"], handler: nil) + wait(for: [test], timeout: 10) + XCTAssert(app.alerts["錯誤"].staticTexts["密碼錯誤,請再試一次"].exists) + } + + func testWrongPassword() { + app.textFields["usernameField"].tap() + app.textFields["usernameField"].typeText("ck1060535") + app.secureTextFields["passwordField"].tap() + app.secureTextFields["passwordField"].typeText("aa") + app.buttons["登入"].tap() + let test = expectation(for: NSPredicate(format: "exists == 1"), evaluatedWith: app.alerts["錯誤"], handler: nil) + wait(for: [test], timeout: 10) + XCTAssert(app.alerts["錯誤"].staticTexts["密碼錯誤,請再試一次"].exists) + } + + func testLogin() { + app.textFields["usernameField"].tap() + app.textFields["usernameField"].typeText("tUsername") + app.secureTextFields["passwordField"].tap() + app.secureTextFields["passwordField"].typeText("tPassword") + app.buttons["登入"].tap() + expectation(for: NSPredicate(format: "exists == 1"), evaluatedWith: app.navigationBars["choiceController"], handler: nil) + waitForExpectations(timeout: 10, handler: nil) + } + +}