Skip to content

Commit 1862c67

Browse files
CoderOMasterCoderOMasterdrpowell
authored
Porting tests from archived repository of OpenPAYGO-Token (EnAccess#27)
* Update .gitignore to include additional files * added simulator * Delete simulators directory * refacotring * readme updated * lint-ed changes * changes * readme_fix * more_formatting * test: email attribution check * resolved changes * old revert * spacing --------- Co-authored-by: CoderOMaster <you@example.com> Co-authored-by: CoderOMaster <123456+username@users.noreply.github.com>
1 parent 28d1d17 commit 1862c67

10 files changed

Lines changed: 1099 additions & 0 deletions

openpaygo/token_decode.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ def get_activation_value_count_and_type_from_token(
134134

135135
@classmethod
136136
def _count_is_valid(cls, count, last_count, value, type, used_counts):
137+
137138
if value == OpenPAYGOTokenShared.COUNTER_SYNC_VALUE:
138139
if count > (last_count - cls.MAX_TOKEN_JUMP):
139140
return True

test/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# OpenPAYGO-Token Test
2+
3+
To run the test, first, create and activate a virtual environment. Then install the module and run the test:
4+
5+
```bash
6+
uv run python test/simple_scenario_test.py
7+
uv run python test/full_test_procedure.py
8+
```

test/__init__.py

Whitespace-only changes.

test/full_test_procedure.py

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
import codecs
2+
3+
from helpers import (
4+
ADD_TIME,
5+
DISABLE_VALUE,
6+
SET_TIME,
7+
generate_from_device_data,
8+
test_accepted_validator,
9+
test_how_many_days_validator,
10+
test_name,
11+
)
12+
13+
from test.simulators.device_simulator import DeviceSimulator
14+
15+
# This tests the device simulator against the full test procedure
16+
17+
18+
def run_core_token_tests(device_data, device_simulator):
19+
test = "We enter an invalid token"
20+
token_g1 = "123 456 789"
21+
test_accepted_validator(device_simulator, "G1", token_g1, -1, description=test)
22+
23+
test = "We enter a valid token for setting one day"
24+
device_data, token_g2 = generate_from_device_data(
25+
device_data, token_type=SET_TIME, value_days=1
26+
)
27+
test_how_many_days_validator(device_simulator, "G2", token_g2, 1, description=test)
28+
29+
test = "We enter a valid token for adding one day"
30+
device_data, token_g3 = generate_from_device_data(
31+
device_data, token_type=ADD_TIME, value_days=1
32+
)
33+
test_how_many_days_validator(device_simulator, "G3", token_g3, 2, description=test)
34+
35+
test = (
36+
"We enter the same Add Time token for 1 day, the days should not be "
37+
"added and the device should signal that the token was already used"
38+
)
39+
test_how_many_days_validator(
40+
device_simulator,
41+
"G4A",
42+
token_g3,
43+
2,
44+
description=test,
45+
accepted_but_used=True,
46+
)
47+
test = (
48+
"We enter the older Set Time token for 1 day, the days should not "
49+
"change and the device should signal that the token was already used"
50+
)
51+
test_how_many_days_validator(
52+
device_simulator,
53+
"G4B",
54+
token_g2,
55+
2,
56+
description=test,
57+
accepted_but_used=True,
58+
)
59+
60+
test = (
61+
"We enter a valid token for setting 30 days and ensures it sets and does "
62+
"not add to the existing"
63+
)
64+
device_data, token_g5 = generate_from_device_data(
65+
device_data, token_type=SET_TIME, value_days=30
66+
)
67+
test_how_many_days_validator(device_simulator, "G5", token_g5, 30, description=test)
68+
69+
test = (
70+
"We enter a valid token for setting 0 days and ensures the device is "
71+
"inactive with the outputs disabled immediately"
72+
)
73+
device_data, token_g6 = generate_from_device_data(
74+
device_data, token_type=SET_TIME, value_days=0
75+
)
76+
test_how_many_days_validator(device_simulator, "G6", token_g6, 0, description=test)
77+
78+
test = (
79+
"We enter 3 consecutive Add Time tokens with the maximum amount of days and "
80+
"ensure that they cumulate properly"
81+
)
82+
for i in range(1, 3 + 1):
83+
device_data, token_g7 = generate_from_device_data(
84+
device_data, token_type=ADD_TIME, value_raw=995
85+
)
86+
test_how_many_days_validator(
87+
device_simulator,
88+
test_name("G7", i),
89+
token_g7,
90+
value_raw=995 * i,
91+
device_data=device_data,
92+
description=test,
93+
)
94+
test = ""
95+
96+
test = (
97+
"We enter 21 consecutive Set Time tokens for 1, 2, 3, … 21 days "
98+
"each with a count 30 higher than the other. The validation of the "
99+
"token should not take more than 5 seconds"
100+
)
101+
for i in range(1, 21 + 1):
102+
device_data, token_g8 = generate_from_device_data(
103+
device_data,
104+
token_type=SET_TIME,
105+
value_days=i,
106+
token_count=device_data["token_count"] + 29,
107+
)
108+
test_how_many_days_validator(
109+
device_simulator,
110+
test_name("G8", i),
111+
token_g8,
112+
value_days=i,
113+
device_data=device_data,
114+
description=test,
115+
)
116+
test = ""
117+
118+
test = "We enter a PAYG Disable token into the device"
119+
device_data, token_g9 = generate_from_device_data(
120+
device_data, token_type=SET_TIME, value_raw=DISABLE_VALUE
121+
)
122+
test_how_many_days_validator(
123+
device_simulator, "G9", token_g9, None, description=test
124+
)
125+
126+
test = "We enter a Set Time token for 0 day, it should relock the device"
127+
device_data, token_g10 = generate_from_device_data(
128+
device_data, token_type=SET_TIME, value_days=0
129+
)
130+
test_how_many_days_validator(
131+
device_simulator, "G10", token_g10, 0, description=test
132+
)
133+
134+
test = (
135+
"We enter a PAYG Disable token to relock the device, then enter a Add "
136+
"Time token with 0 day, it should NOT relock the device (Optional)"
137+
)
138+
device_data, token_g11a = generate_from_device_data(
139+
device_data, token_type=SET_TIME, value_raw=DISABLE_VALUE
140+
)
141+
test_how_many_days_validator(
142+
device_simulator, "G11A", token_g11a, None, description=test
143+
)
144+
device_data, token_g11b = generate_from_device_data(
145+
device_data, token_type=ADD_TIME, value_days=0
146+
)
147+
test_how_many_days_validator(device_simulator, "G11B", token_g11b, None)
148+
149+
test = (
150+
"We deactivate the device with a Set Time of 0 days. We then wait "
151+
"48 hours before entering a Add Time of 1 day and ensuring that the "
152+
"days late are not considered in the activation time"
153+
)
154+
device_data, token_g12a = generate_from_device_data(
155+
device_data, token_type=SET_TIME, value_days=0
156+
)
157+
test_how_many_days_validator(
158+
device_simulator, "G12A", token_g12a, 0, description=test
159+
)
160+
device_data, token_g12b = generate_from_device_data(
161+
device_data, token_type=ADD_TIME, value_days=1
162+
)
163+
test_how_many_days_validator(device_simulator, "G12B", token_g12b, 1)
164+
165+
return device_data
166+
167+
168+
def run_unordered_entry_tests(device_data, device_simulator):
169+
test = (
170+
"We generate 3 Add Time tokens, then enter the 3rd, then first, then "
171+
"second and ensure the days are added properly"
172+
)
173+
device_data, token_u1a = generate_from_device_data(
174+
device_data, token_type=SET_TIME, value_days=60
175+
)
176+
test_how_many_days_validator(
177+
device_simulator, "U1A", token_u1a, 60, description=test
178+
)
179+
device_data, token_u1b = generate_from_device_data(
180+
device_data, token_type=ADD_TIME, value_days=10
181+
)
182+
device_data, token_u1c = generate_from_device_data(
183+
device_data, token_type=ADD_TIME, value_days=5
184+
)
185+
device_data, token_u1d = generate_from_device_data(
186+
device_data, token_type=ADD_TIME, value_days=1
187+
)
188+
test_how_many_days_validator(device_simulator, "U1B", token_u1d, 61)
189+
test_how_many_days_validator(device_simulator, "U1C", token_u1b, 71)
190+
test_how_many_days_validator(device_simulator, "U1D", token_u1c, 76)
191+
192+
test = (
193+
"We generate an Add Time, a Set Time and another Add Time token. We "
194+
"enter the set time and ensure that the older Add Time does not work "
195+
"but the newer does"
196+
)
197+
device_data, token_u2a = generate_from_device_data(
198+
device_data, token_type=ADD_TIME, value_days=5
199+
)
200+
device_data, token_u2b = generate_from_device_data(
201+
device_data, token_type=SET_TIME, value_days=10
202+
)
203+
device_data, token_u2c = generate_from_device_data(
204+
device_data, token_type=ADD_TIME, value_days=3
205+
)
206+
test_how_many_days_validator(
207+
device_simulator, "U2A", token_u2b, 10, description=test
208+
)
209+
test_how_many_days_validator(
210+
device_simulator, "U2B", token_u2a, 10, accepted_but_used=True
211+
)
212+
test_how_many_days_validator(device_simulator, "U2C", token_u2c, 13)
213+
214+
test = (
215+
"We generate an Add Time token and a Disable PAYG token, we enter the "
216+
"Disable PAYG token and then the Add Time token should be refused"
217+
)
218+
device_data, token_u3a = generate_from_device_data(
219+
device_data, token_type=ADD_TIME, value_days=1
220+
)
221+
device_data, token_u3b = generate_from_device_data(
222+
device_data, token_type=ADD_TIME, value_raw=DISABLE_VALUE
223+
)
224+
test_how_many_days_validator(
225+
device_simulator, "U3A", token_u3b, None, description=test
226+
)
227+
test_how_many_days_validator(
228+
device_simulator, "U3B", token_u3a, None, accepted_but_used=True
229+
)
230+
231+
return device_data
232+
233+
234+
if __name__ == "__main__":
235+
device_data = {
236+
"serial_number": "XXX",
237+
"starting_code": 516959010,
238+
"key": "bc41ec9530f6dac86b1a29ab82edc5fb",
239+
"restricted_digit_set": False,
240+
"time_divider": 1,
241+
"token_count": 1,
242+
}
243+
device_simulator = DeviceSimulator(
244+
device_data["starting_code"],
245+
codecs.decode(device_data["key"], "hex"),
246+
restricted_digit_set=device_data["restricted_digit_set"],
247+
waiting_period_enabled=False,
248+
)
249+
device_data = run_core_token_tests(device_data, device_simulator)
250+
device_data = run_unordered_entry_tests(device_data, device_simulator)

test/helpers.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import codecs
2+
3+
import openpaygo
4+
from openpaygo.token_shared import TokenType
5+
6+
SET_TIME = TokenType.SET_TIME
7+
ADD_TIME = TokenType.ADD_TIME
8+
DISABLE_VALUE = 998
9+
10+
START_RED = "\033[91m"
11+
END_RED = "\033[0m"
12+
13+
14+
def generate_from_device_data(
15+
device_data, token_type, value_raw=None, value_days=None, token_count=None
16+
):
17+
assert (value_days is not None) or (value_raw is not None)
18+
if value_raw is None:
19+
value_raw = value_days * device_data["time_divider"]
20+
device_data["token_count"], token = (
21+
openpaygo.token_encode.OpenPAYGOTokenEncoder.generate_standard_token(
22+
starting_code=device_data["starting_code"],
23+
key=codecs.decode(device_data["key"], "hex"),
24+
value=value_raw,
25+
count=token_count or device_data["token_count"],
26+
restricted_digit_set=device_data["restricted_digit_set"],
27+
mode=token_type,
28+
)
29+
)
30+
token = str(token).rjust(9, "0")
31+
token = " ".join([token[i : i + 3] for i in range(0, len(token), 3)])
32+
return device_data, token
33+
34+
35+
def test_how_many_days(
36+
test_name, token, value_days=None, value_raw=None, device_data=None, description=""
37+
):
38+
if value_days is None:
39+
if value_raw is not None:
40+
value_days = value_raw / device_data["time_divider"]
41+
else:
42+
value_days = "infinite"
43+
print(
44+
test_name
45+
+ ","
46+
+ token
47+
+ ","
48+
+ str(value_days)
49+
+ " days active"
50+
+ ',"'
51+
+ description
52+
+ '"'
53+
)
54+
55+
56+
def test_accepted(test_name, token, expected, description=""):
57+
expected_string = "Token Accepted" if expected else "Token Refused"
58+
print(test_name + "," + token + "," + expected_string + ',"' + description + '"')
59+
60+
61+
def test_how_many_days_validator(
62+
device_simulator,
63+
test_name,
64+
token,
65+
value_days=None,
66+
value_raw=None,
67+
device_data=None,
68+
description="",
69+
accepted_but_used=False,
70+
):
71+
if value_days is None:
72+
if value_raw is not None:
73+
value_days = value_raw / device_data["time_divider"]
74+
else:
75+
value_days = "infinite"
76+
result = device_simulator.enter_token(token.replace(" ", ""), show_result=False)
77+
if result == 1 or (accepted_but_used and result == -2):
78+
if device_simulator.get_days_remaining() == value_days:
79+
print(test_name + ": Passed")
80+
return
81+
print(START_RED + test_name + ": Failed" + END_RED)
82+
83+
84+
def test_accepted_validator(
85+
device_simulator, test_name, token, expected, description=""
86+
):
87+
if (
88+
device_simulator.enter_token(token.replace(" ", ""), show_result=False)
89+
== expected
90+
):
91+
print(test_name + ": Passed")
92+
return
93+
else:
94+
print(START_RED + test_name + ": Failed" + END_RED)
95+
96+
97+
def test_name(test_base_name, test_number):
98+
return test_base_name + chr(test_number + 64)

0 commit comments

Comments
 (0)