<commit_before>//
//  KeychainAccessTests.swift
//  KeychainAccessTests
//
//  Created by <NAME> on 2014/12/24.
//  Copyright (c) 2014 <NAME>. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import Foundation
import XCTest

import KeychainAccess

class KeychainAccessTests: XCTestCase {

    override func setUp() {
        super.setUp()

        do { try Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared").removeAll() } catch {}
        do { try Keychain(service: "Twitter").removeAll() } catch {}

        do { try Keychain(server: URL(string: "https://example.com")!, protocolType: .https).removeAll() } catch {}
        do { try Keychain(server: URL(string: "https://example.com:443")!, protocolType: .https).removeAll() } catch {}

        do { try Keychain().removeAll() } catch {}
    }

    override func tearDown() {
        super.tearDown()
    }

    // MARK:

    func testGenericPassword() {
        do {
            // Add Keychain items
            let keychain = Keychain(service: "Twitter")

            do { try keychain.set("kishikawa_katsumi", key: "username") } catch {}
            do { try keychain.set("password_1234", key: "password") } catch {}

            let username = try! keychain.get("username")
            XCTAssertEqual(username, "kishikawa_katsumi")

            let password = try! keychain.get("password")
            XCTAssertEqual(password, "<PASSWORD>")
        }

        do {
            // Update Keychain items
            let keychain = Keychain(service: "Twitter")

            do { try keychain.set("katsumi_kishikawa", key: "username") } catch {}
            do { try keychain.set("1234_password", key: "password") } catch {}

            let username = try! keychain.get("username")
            XCTAssertEqual(username, "katsumi_kishikawa")

            let password = try! keychain.get("password")
            XCTAssertEqual(password, "<PASSWORD>")
        }

        do {
            // Remove Keychain items
            let keychain = Keychain(service: "Twitter")

            do { try keychain.remove("username") } catch {}
            do { try keychain.remove("password") } catch {}

            XCTAssertNil(try! keychain.get("username"))
            XCTAssertNil(try! keychain.get("password"))
        }
    }

    func testGenericPasswordSubscripting() {
        do {
            // Add Keychain items
            let keychain = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared")

            keychain["username"] = "kishikawa_katsumi"
            keychain["password"] = "<PASSWORD>"

            let username = keychain["username"]
            XCTAssertEqual(username, "kishikawa_katsumi")

            let password = keychain["password"]
            XCTAssertEqual(password, "<PASSWORD>")
        }

        do {
            // Update Keychain items
            let keychain = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared")

            keychain["username"] = "katsumi_<PASSWORD>"
            keychain["password"] = "<PASSWORD>"

            let username = keychain["username"]
            XCTAssertEqual(username, "katsumi_kishikawa")

            let password = keychain["password"]
            XCTAssertEqual(password, "<PASSWORD>")
        }

        do {
            // Remove Keychain items
            let keychain = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared")

            keychain["username"] = nil
            keychain["password"] = nil

            XCTAssertNil(keychain["username"])
            XCTAssertNil(keychain["password"])
        }
    }

    // MARK:

    func testInternetPassword() {
        do {
            // Add Keychain items
            let keychain = Keychain(server: URL(string: "https://kishikawakatsumi.com")!, protocolType: .https)

            do { try keychain.set("kishikawa_katsumi", key: "username") } catch {}<commit_msg>Add tests for access group<commit_after>//
//  KeychainAccessTests.swift
//  KeychainAccessTests
//
//  Created by <NAME> on 2014/12/24.
//  Copyright (c) 2014 <NAME>. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import Foundation
import XCTest

import KeychainAccess

class KeychainAccessTests: XCTestCase {

    override func setUp() {
        super.setUp()

        do { try Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared").removeAll() } catch {}
        do { try Keychain(service: "Twitter").removeAll() } catch {}

        do { try Keychain(server: URL(string: "https://example.com")!, protocolType: .https).removeAll() } catch {}
        do { try Keychain(server: URL(string: "https://example.com:443")!, protocolType: .https).removeAll() } catch {}

        do { try Keychain().removeAll() } catch {}
    }

    override func tearDown() {
        super.tearDown()
    }

    // MARK:

    func testGenericPassword() {
        do {
            // Add Keychain items
            let keychain = Keychain(service: "Twitter")

            do { try keychain.set("kishikawa_katsumi", key: "username") } catch {}
            do { try keychain.set("password_1234", key: "password") } catch {}

            let username = try! keychain.get("username")
            XCTAssertEqual(username, "kishikawa_katsumi")

            let password = try! keychain.get("password")
            XCTAssertEqual(password, "<PASSWORD>")
        }

        do {
            // Update Keychain items
            let keychain = Keychain(service: "Twitter")

            do { try keychain.set("katsumi_kishikawa", key: "username") } catch {}
            do { try keychain.set("1234_password", key: "password") } catch {}

            let username = try! keychain.get("username")
            XCTAssertEqual(username, "katsumi_kishikawa")

            let password = try! keychain.get("password")
            XCTAssertEqual(password, "<PASSWORD>")
        }

        do {
            // Remove Keychain items
            let keychain = Keychain(service: "Twitter")

            do { try keychain.remove("username") } catch {}
            do { try keychain.remove("password") } catch {}

            XCTAssertNil(try! keychain.get("username"))
            XCTAssertNil(try! keychain.get("password"))
        }
    }

    func testGenericPasswordSubscripting() {
        do {
            // Add Keychain items
            let keychain = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared")

            keychain["username"] = "kishikawa_katsumi"
            keychain["password"] = "<PASSWORD>"

            let username = keychain["username"]
            XCTAssertEqual(username, "kishikawa_katsumi")

            let password = keychain["password"]
            XCTAssertEqual(password, "<PASSWORD>")
        }

        do {
            // Update Keychain items
            let keychain = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared")

            keychain["username"] = "katsumi_kishikawa"
            keychain["password"] = "<PASSWORD>"

            let username = keychain["username"]
            XCTAssertEqual(username, "katsumi_kishikawa")

            let password = keychain["password"]
            XCTAssertEqual(password, "<PASSWORD>")
        }

        do {
            // Remove Keychain items
            let keychain = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared")

            keychain["username"] = nil
            keychain["password"] = nil

            XCTAssertNil(keychain["username"])
            XCTAssertNil(keychain["password"])
        }
    }

    func testGenericPasswordWithAccessGroup1() {
        do {
            // Add Keychain items
            let keychain = Keychain(service: "Twitter")
            let keychainWithAccessGroup = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared")

            do { try keychain.set("kishikawa_katsumi", key: "username") } catch {}
            do { try keychain.set("password_1234", key: "password") } catch {}
            do { try keychainWithAccessGroup.set("kishikawa_katsumi_access_group", key: "username") } catch {}
            do { try keychainWithAccessGroup.set("password_1234_access_group", key: "password") } catch {}

            XCTAssertEqual(try! keychain.get("username"), "kishikawa_katsumi")
            XCTAssertEqual(try! keychain.get("password"), "<PASSWORD>")

            XCTAssertEqual(try! keychainWithAccessGroup.get("username"), "kishikawa_katsumi_access_group")
            XCTAssertEqual(try! keychainWithAccessGroup.get("password"), "password_<PASSWORD>_group")
        }

        do {
            // Update Keychain items
            let keychain = Keychain(service: "Twitter")
            let keychainWithAccessGroup = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared")

            do { try keychain.set("katsumi_kishikawa", key: "username") } catch {}
            do { try keychain.set("1234_password", key: "password") } catch {}
            do { try keychainWithAccessGroup.set("katsumi_kishikawa_access_group", key: "username") } catch {}
            do { try keychainWithAccessGroup.set("1234_password_access_group", key: "password") } catch {}

            XCTAssertEqual(try! keychain.get("username"), "katsumi_kishikawa")
            XCTAssertEqual(try! keychain.get("password"), "<PASSWORD>")

            XCTAssertEqual(try! keychainWithAccessGroup.get("username"), "katsumi_kishikawa_access_group")
            XCTAssertEqual(try! keychainWithAccessGroup.get("password"), "<PASSWORD>")
        }

        do {
            // Remove Keychain items
            let keychain = Keychain(service: "Twitter")
            let keychainWithAccessGroup = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared")

            XCTAssertNotNil(try! keychainWithAccessGroup.get("username"))
            XCTAssertNotNil(try! keychainWithAccessGroup.get("password"))

            do { try keychainWithAccessGroup.remove("username") } catch {}
            do { try keychainWithAccessGroup.remove("password") } catch {}


            XCTAssertNil(try! keychainWithAccessGroup.get("username"))
            XCTAssertNil(try! keychainWithAccessGroup.get("password"))

            XCTAssertNotNil(try! keychain.get("username"))
            XCTAssertNotNil(try! keychain.get("password"))

            do { try keychain.remove("username") } catch {}
            do { try keychain.remove("password") } catch {}

            XCTAssertNil(try! keychain.get("username"))
            XCTAssertNil(try! keychain.get("password"))
        }
    }

    func testGenericPasswordWithAccessGroup2() {
        do {
            // Add Keychain items
            let keychain = Keychain(service: "Twitter")
            let keychainWithAccessGroup = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared")

            do { try keychain.set("kishikawa_katsumi", key: "username") } catch {}
            do { try keychain.set("password_1234", key: "password") } catch {}
            do { try keychainWithAccessGroup.set("kishikawa_katsumi_access_group", key: "username") } catch {}
            do { try keychainWithAccessGroup.set("password_1234_access_group", key: "password") } catch {}

            XCTAssertEqual(try! keychain.get("username"), "kishikawa_katsumi")
            XCTAssertEqual(try! keychain.get("password"), "<PASSWORD>")

            XCTAssertEqual(try! keychainWithAccessGroup.get("username"), "kishikawa_katsumi_access_group")
            XCTAssertEqual(try! keychainWithAccessGroup.get("password"), "<PASSWORD>")
        }

        do {
            // Update Keychain items
            let keychain = Keychain(service: "Twitter")
            let keychainWithAccessGroup = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared")

            do { try keychain.set("katsumi_kishikawa", key: "username") } catch {}
            do { try keychain.set("1234_password", key: "password") } catch {}
            do { try keychainWithAccessGroup.set("katsumi_kishikawa_access_group", key: "username") } catch {}
            do { try keychainWithAccessGroup.set("1234_password_access_group", key: "password") } catch {}

            XCTAssertEqual(try! keychain.get("username"), "katsumi_kishikawa")
            XCTAssertEqual(try! keychain.get("password"), "<PASSWORD>")

            XCTAssertEqual(try! keychainWithAccessGroup.get("username"), "katsumi_kishikawa_access_group")
            XCTAssertEqual(try! keychainWithAccessGroup.get("password"), "<PASSWORD>")
        }

        do {
            // Remove Keychain items
            let keychain = Keychain(service: "Twitter")
            let keychainWithAccessGroup = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared")

            XCTAssertNotNil(try! keychainWithAccessGroup.get("username"))
            XCTAssertNotNil(try! keychainWithAccessGroup.get("password"))

            do { try keychain.remove("username") } catch {}
            do { try keychain.remove("password") } catch {}

            // If the access group is empty, the query will match all access group. So delete all values in other access groups.
            XCTAssertNil(try! keychain.get("username"))
            XCTAssertNil(try! keychain.get("password"))

            XCTAssertNil(try! keychainWithAccessGroup.get("username"))
            XCTAssertNil(try! keychainWithAccessGroup.get("password"))
        }
    }

    // MARK:

    func testInternetPassword() {
        do {
            // Add Keychain items
            let keychain = Keychain(server: URL(string: "https://kishikawakatsumi.com")!, protocolType: .https)

            do { try keychain.set("kishikawa_katsumi", key: "username") } catch {}
{'fraction_non_alphanumeric': 0.11621087524701983, 'fraction_numerical': 0.008669599031044814, 'mean_word_length': 2.6197508075680664, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 28, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1454025', 'n_tokens_mistral': 4494, 'n_tokens_neox': 4236, 'n_words': 1107}