Revision control

1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
* License, v. 2.0. If a copy of the MPL was not distributed with this
3
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
@testable import Account
6
@testable import Client
7
import Foundation
8
import FxA
9
import SwiftyJSON
10
import XCTest
11
12
class FxAPushMessageTest: XCTestCase {
13
func testMessage_subscriptionDecryption() {
14
var userInfo: [AnyHashable: Any] = [
15
"chid": "034f52789f7b44ecaf119cc59231cdc1",
16
"enc": "keyid=p256dh;salt=mYBHM3B_oXlEjV0HfgHZ1A",
17
"body": "_tZf65gKC23STnTNuhtSSbrg1LScGiLjO4GOIuHlCGIFFEzcwsB-J-s3pe3qu2d24A-sKwVyolmShlMBEvEX_34f6FgXMs3k35g4u5STKgJMQxZ8VFDjtQqQfxfSIEt35pdKaPwXKH2zbs0xHC3qEJ0YMc60Eq8uAuQF7FQZ7ts",
18
"cryptokey": "keyid=p256dh;dh=BNLZ2IWMNGioofzMBnSijySib0Pa-lwgBfLYIhqvvmKxprKgEh6JCDB2DBUmj9BuJCk6xJvBbPd-4x_8tb-qIPM;p256ecdsa=BP-OR33RzQSlrzD7_d1kYE9i9WjSIQAKTuhHxYNiPEF0i-wxeNIIwxthwU7zBTbumyxFUeydrmxcVKXugjBImRU",
19
"con": "aesgcm",
20
"ver": "gAAAAABY5hUl_Pi1bVI4ptqKzPWq_aulqXEO1eOx_ncUuwoz8zItWWLA4Ix1ZbDLTOkurqK1vE3N3y1ZXsp_MZ69QJYRuWg5V_3T_XUNVBxj8dnDcNAE-ep9_M5xeKiNdngdww-cqqMOxf-tI5ZoR2nQFqWSs51XGwMMIdsGNmUPqnR4w2Rzt6FYz-AsGCrHXJ3bmYbwpq4P",
21
]
22
23
let subscription = PushSubscription(channelID: "channel",
24
endpoint: URL(string: "https://example.ru")!,
25
p256dhPrivateKey: "UDnicgor_Il7cLNTqSt--SrEblNBbgPA2yXAQ_b31xI",
26
p256dhPublicKey: "BB4XdAhpVVU45NYSXHpRiubMYoaeb0A-y5aSGE437YKGHQihlvlZMv5D0ebK6WmFqzpIr217Kv9oCbZVDp1KGK4",
27
authKey: "0gH7RiYYMhfHDQ1L1X4RMw")
28
29
let body = userInfo["body"] as! String
30
let enc = userInfo["enc"] as! String
31
let cryptokey = userInfo["cryptokey"] as! String
32
33
guard let plaintext = subscription.aesgcm(payload: body, encryptionHeader: enc, cryptoHeader: cryptokey) else {
34
return XCTFail("Decryption failed")
35
}
36
37
let json = JSON(parseJSON: plaintext)
38
39
XCTAssertEqual(json["command"].stringValue, "fxaccounts:device_connected")
40
}
41
42
func testMessageHandler() {
43
let subscription = PushSubscription(channelID: "channel",
44
endpoint: URL(string: "https://example.ru")!,
45
p256dhPrivateKey: "t7dcZIN4w37UYjE6u3lBLB0WOShxqelkbJFKKzMDSsE",
46
p256dhPublicKey: "BIXFDlhppL2lc5GcIXbGPa1iVdJn5ULYaF1ltJY9Qm17-tIC_9eEZXtalPpMRXsFmEKhdn2ttg3KQ3t-ztQ3ShQ",
47
authKey: "a8E3EO5F6FFWdv4hAGyGyw")
48
49
let userInfo: [AnyHashable: Any] = [
50
AnyHashable("chid"): "f6defa012a6249e58bbfbf2995f8d425",
51
AnyHashable("enc"): "keyid=p256dh;salt=nslkEsUqUg5sQ7_sRZfOjg",
52
AnyHashable("body"): "Q1t-ttSwQMxUI64Ls3vOU-hE_qg1AIUzyLQSpEkx-8JITh5UJ7oq25faEc8XPoTYQoaHQ2d--QIK_yVorbt-0Yr7IO4BmtSSX-e4kSx76fWzqKjEpEt7Vr3Av5seEBeoAT2FZRzehkFjNVWoTw",
53
AnyHashable("cryptokey"): "keyid=p256dh;dh=BNfUPK_8eUTZGOyXq07lthBfHeIxC2B7L_gF3cMGK1jVfDe9tlgxpHD_mbKrt3p12d7_O__wizhne2a1Eb7pZgk;p256ecdsa=BFSuld8S4PbRcgGe3OQPN9NyIOXx-ccUIMb0q6nIpH7Qf894wz0TIQTXQ7I7pWjZiN9KCdYVjNhyPtr1--37ois",
54
AnyHashable("con"): "aesgcm",
55
AnyHashable("ver"): "gAAAAABZLbG-m7EHhcMdrqs51SkESIZHsZjvw2QIu8LOeXxcKEy6wDVCprOKFAfJU44cinfJcDtCnO9EEyzpFt5e0HBDCLybGyThoZzmiod6zTLhTfAKZe-SyElSVCL0UDpJ_-U3UTUUHUaJXeRf0z6NvFM-uL39Jy-dwr3cuJoSDIcTPdChRPFiIS1hwokqMlxOn36azxOi",
56
]
57
58
let profile = MockProfile()
59
60
let account = Account.FirefoxAccount(
61
configuration: FirefoxAccountConfigurationLabel.production.toConfiguration(prefs: profile.prefs),
62
email: "testtest@test.com",
63
uid: "uid",
64
deviceRegistration: nil,
65
declinedEngines: nil,
66
stateKeyLabel: "xxx",
67
state: SeparatedState(),
68
deviceName: "My iPhone")
69
70
let registration = PushRegistration(uaid: "uaid", secret: "secret", subscription: subscription)
71
72
account.pushRegistration = registration
73
profile.setAccount(account)
74
75
let handler = FxAPushMessageHandler(with: profile)
76
77
let expectation = XCTestExpectation()
78
handler.handle(userInfo: userInfo).upon { maybe in
79
XCTAssertTrue(maybe.isSuccess)
80
XCTAssertEqual(maybe.successValue!, PushMessage.collectionChanged(collections: ["clients", "tabs"]))
81
expectation.fulfill()
82
}
83
wait(for: [expectation], timeout: 10)
84
}
85
86
func createHandler(_ profile: Profile = MockProfile()) -> FxAPushMessageHandler {
87
let account = Account.FirefoxAccount(
88
configuration: FirefoxAccountConfigurationLabel.production.toConfiguration(prefs: profile.prefs),
89
email: "testtest@test.com",
90
uid: "uid",
91
deviceRegistration: nil,
92
declinedEngines: nil,
93
stateKeyLabel: "xxx",
94
state: SeparatedState(),
95
deviceName: "My iPhone")
96
97
profile.setAccount(account)
98
99
return FxAPushMessageHandler(with: profile)
100
}
101
102
func test_deviceConnected() {
103
let handler = createHandler()
104
105
let expectation = XCTestExpectation()
106
handler.handle(plaintext: "{\"command\":\"fxaccounts:device_connected\",\"data\":{\"deviceName\": \"Use Nightly on Desktop\"}}").upon { maybe in
107
XCTAssertTrue(maybe.isSuccess)
108
guard let message = maybe.successValue else {
109
return expectation.fulfill()
110
}
111
XCTAssertEqual(message, PushMessage.deviceConnected("Use Nightly on Desktop"))
112
expectation.fulfill()
113
}
114
wait(for: [expectation], timeout: 10)
115
}
116
117
func test_deviceDisconnected() {
118
let profile = MockProfile()
119
let handler = createHandler(profile)
120
let prefs = profile.prefs
121
122
let expectation = XCTestExpectation()
123
handler.handle(plaintext: "{\"command\":\"fxaccounts:device_disconnected\",\"data\":{\"id\": \"not_this_device\"}}").upon { maybe in
124
XCTAssertTrue(maybe.isSuccess)
125
guard let message = maybe.successValue else {
126
return expectation.fulfill()
127
}
128
XCTAssertEqual(message.messageType, .deviceDisconnected)
129
XCTAssertFalse(prefs.boolForKey(PendingAccountDisconnectedKey) ?? false)
130
expectation.fulfill()
131
}
132
wait(for: [expectation], timeout: 10)
133
134
}
135
136
func test_thisDeviceDisconnected() {
137
let profile = MockProfile()
138
let handler = createHandler(profile)
139
140
let deviceRegistration = FxADeviceRegistration(id: "this-device-id", version: 1, lastRegistered: 0)
141
profile.account?.deviceRegistration = deviceRegistration
142
143
let prefs = profile.prefs
144
145
let expectation = XCTestExpectation()
146
handler.handle(plaintext: "{\"command\":\"fxaccounts:device_disconnected\",\"data\":{\"id\": \"\(deviceRegistration.id)\"}}").upon { maybe in
147
guard let message = maybe.successValue else {
148
return expectation.fulfill()
149
}
150
XCTAssertEqual(message, PushMessage.thisDeviceDisconnected)
151
XCTAssertTrue(prefs.boolForKey(PendingAccountDisconnectedKey) ?? false)
152
expectation.fulfill()
153
}
154
wait(for: [expectation], timeout: 10)
155
156
}
157
}