1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
// Author: cirakg & claude ai
// Summary: Helpers for the settings tests: a form store with every default, form builders and a job runner (fake data only).
import Toybox.Application;
import Toybox.Lang;
import Toybox.Test;
(:test)
module SettingsFixtures {
function vault() as Vault {
return new Vault(new MemoryBackend(), new FakeTime());
}
// A store holding every form field at its default (as properties.xml).
function store() as Forms.MemoryStore {
var s = new Forms.MemoryStore();
copy(s, OtpForm.defaults() as Dictionary<String, Application.Properties.ValueType>);
copy(s, CodeForm.defaults() as Dictionary<String, Application.Properties.ValueType>);
copy(s, ManageForm.defaults() as Dictionary<String, Application.Properties.ValueType>);
for (var i = 1; i <= SettingsJob.IMPORT_TEXT_FIELDS; i++) {
s.set("impText" + i, "");
}
s.set("impMode", 0);
s.set("impLocked", false);
var off = ["otpAdd", "codeAdd", "mgApply", "impApply"];
for (var i = 0; i < off.size(); i++) {
s.set(off[i] as String, false);
}
return s;
}
function copy(s as Forms.MemoryStore, values as Dictionary<String, Application.Properties.ValueType>) as Void {
var keys = values.keys();
for (var i = 0; i < keys.size(); i++) {
s.set(keys[i], values[keys[i]] as Application.Properties.ValueType);
}
}
// Fill in Add OTP and turn its switch on.
function otp(s as Forms.Store, type as Number, issuer as String, account as String, secret as String) as Void {
s.set("otpType", type);
s.set("otpIssuer", issuer);
s.set("otpAccount", account);
s.set("otpSecret", secret);
s.set(OtpForm.SWITCH, true);
}
function code(s as Forms.Store, symbology as Number, name as String, payload as String) as Void {
s.set("codeName", name);
s.set("codeSymbology", symbology);
s.set("codePayload", payload);
s.set(CodeForm.SWITCH, true);
}
function manage(s as Forms.Store, id as String, action as Number) as Void {
s.set("mgId", id);
s.set("mgAction", action);
s.set(ManageForm.SWITCH, true);
}
// Run every form to the end, as the app's timer would.
function run(v as Vault, s as Forms.Store) as SettingsJob {
var job = new SettingsJob(v, s, 1800000000l);
Jobs.runToCompletion(job, 1);
return job;
}
function text(s as Forms.Store, key as String) as String {
var v = s.get(key);
return v instanceof String ? v : "";
}
// True when the field's text contains `part`; logs it otherwise.
function contains(logger as Test.Logger, s as Forms.Store, key as String, part as String) as Boolean {
var value = text(s, key);
if (value.find(part) != null) {
return true;
}
logger.error(key + " = '" + value + "', expected to contain '" + part + "'");
return false;
}
// True when some line starts with `prefix`.
function hasLine(lines as Array<String>, prefix as String) as Boolean {
for (var i = 0; i < lines.size(); i++) {
if (lines[i].find(prefix) == 0) {
return true;
}
}
return false;
}
// A string of n copies of `unit`.
function repeat(unit as String, n as Number) as String {
var out = "";
for (var i = 0; i < n; i++) {
out += unit;
}
return out;
}
// The secret of an entry, as text (the fixtures use ASCII keys).
function secretOf(v as Vault, id as String) as String {
var e = v.open(id);
var text = Bytes.toUtf8(e.kind == Entry.KIND_OTP ? e.secret as ByteArray : e.payload as ByteArray);
e.wipeSecrets();
return text != null ? text : "";
}
}
|