ronin-web-user_agents 0.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,511 @@
1
+ require 'spec_helper'
2
+ require 'ronin/web/user_agents/chrome'
3
+
4
+ describe Ronin::Web::UserAgents::Chrome do
5
+ describe ".build" do
6
+ let(:chrome_version) { '100.0.4758.80' }
7
+
8
+ context "when given `os: :windows`" do
9
+ let(:os) { :windows }
10
+
11
+ context "but os_version: is not given" do
12
+ it do
13
+ expect {
14
+ subject.build(chrome_version: chrome_version, os: os)
15
+ }.to raise_error(ArgumentError,"os: #{os.inspect} also requires an os_version: value")
16
+ end
17
+ end
18
+
19
+ Ronin::Web::UserAgents::OS::Windows::VERSIONS.each do |version_id,version_string|
20
+ context "when given `os_version: #{version_id.inspect}`" do
21
+ let(:os_version) { version_id }
22
+ let(:windows_version) { version_string }
23
+
24
+ it "must include 'Windows NT #{version_string}' in the extensions" do
25
+ expect(
26
+ subject.build(
27
+ chrome_version: chrome_version,
28
+ os: os,
29
+ os_version: os_version
30
+ )
31
+ ).to eq("Mozilla/5.0 (Windows NT #{windows_version}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Safari/537.36")
32
+ end
33
+
34
+ Ronin::Web::UserAgents::OS::Windows::ARCHES.each do |arch_id,arch_string|
35
+
36
+ context "and when `arch: #{arch_id.inspect}` is given" do
37
+ let(:arch) { arch_id }
38
+ let(:windows_arch) { arch_string }
39
+
40
+ if arch_id
41
+ it "must appned '#{arch_string}' after the Windows version" do
42
+ expect(
43
+ subject.build(
44
+ chrome_version: chrome_version,
45
+ os: os,
46
+ os_version: os_version,
47
+ arch: arch
48
+ )
49
+ ).to eq("Mozilla/5.0 (Windows NT #{windows_version}; #{windows_arch}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Safari/537.36")
50
+ end
51
+
52
+ context "and when given the `chrome_version:` keyword argument" do
53
+ let(:chrome_version) { '1.2.3' }
54
+
55
+ it "must use the specified `chrome_version:` value" do
56
+ expect(
57
+ subject.build(
58
+ chrome_version: chrome_version,
59
+ os: os,
60
+ os_version: os_version,
61
+ arch: arch
62
+ )
63
+ ).to eq("Mozilla/5.0 (Windows NT #{windows_version}; #{windows_arch}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Safari/537.36")
64
+ end
65
+ end
66
+ else # `arch: nil` edge-case
67
+ it "must not appned any additional fields" do
68
+ expect(
69
+ subject.build(
70
+ chrome_version: chrome_version,
71
+ os: os,
72
+ os_version: os_version,
73
+ arch: arch
74
+ )
75
+ ).to eq("Mozilla/5.0 (Windows NT #{windows_version}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Safari/537.36")
76
+ end
77
+
78
+ context "and when given the `chrome_version:` keyword argument" do
79
+ let(:chrome_version) { '1.2.3' }
80
+
81
+ it "must use the specified `chrome_version:` value" do
82
+ expect(
83
+ subject.build(
84
+ chrome_version: chrome_version,
85
+ os: os,
86
+ os_version: os_version,
87
+ arch: arch
88
+ )
89
+ ).to eq("Mozilla/5.0 (Windows NT #{windows_version}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Safari/537.36")
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ context "and when given the `chrome_version:` keyword argument" do
97
+ let(:chrome_version) { '1.2.3' }
98
+
99
+ it "must use the specified `chrome_version:` value" do
100
+ expect(
101
+ subject.build(
102
+ chrome_version: chrome_version,
103
+ os: os,
104
+ os_version: os_version
105
+ )
106
+ ).to eq("Mozilla/5.0 (Windows NT #{windows_version}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Safari/537.36")
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ context "when given `os: :macos`" do
114
+ let(:os) { :macos }
115
+
116
+ Ronin::Web::UserAgents::OS::MacOS::VERSIONS_UNDERSCORED.each do |version,underscored_version|
117
+ context "and when given `os_version: '#{version}'`" do
118
+ let(:os_version) { version }
119
+
120
+ it "must include 'Macintosh; Intel Mac OS X #{underscored_version}' in the extensions" do
121
+ expect(
122
+ subject.build(
123
+ chrome_version: chrome_version,
124
+ os: os,
125
+ os_version: os_version
126
+ )
127
+ ).to eq("Mozilla/5.0 (Macintosh; Intel Mac OS X #{underscored_version}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Safari/537.36")
128
+ end
129
+
130
+ context "when given `chrome_version: ...`" do
131
+ let(:chrome_version) { '1.2.3' }
132
+
133
+ it "must use the specified `chrome_version:` value" do
134
+ expect(
135
+ subject.build(
136
+ chrome_version: chrome_version,
137
+ os: os,
138
+ os_version: os_version
139
+ )
140
+ ).to eq("Mozilla/5.0 (Macintosh; Intel Mac OS X #{underscored_version}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Safari/537.36")
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+ context "and when given an unknown `os_version:` value" do
147
+ let(:os_version) { '12.0.0' }
148
+ let(:underscored_version) { os_version.tr('.','_') }
149
+
150
+ it "must include 'Macintosh; Intel Mac OS X X_Y_Z' in the extensions" do
151
+ expect(
152
+ subject.build(
153
+ chrome_version: chrome_version,
154
+ os: os,
155
+ os_version: os_version
156
+ )
157
+ ).to eq("Mozilla/5.0 (Macintosh; Intel Mac OS X #{underscored_version}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Safari/537.36")
158
+ end
159
+
160
+ context "and when given the `chrome_version:` keyword argument" do
161
+ let(:chrome_version) { '1.2.3' }
162
+
163
+ it "must use the specified `chrome_version:` value" do
164
+ expect(
165
+ subject.build(
166
+ chrome_version: chrome_version,
167
+ os: os,
168
+ os_version: os_version
169
+ )
170
+ ).to eq("Mozilla/5.0 (Macintosh; Intel Mac OS X #{underscored_version}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Safari/537.36")
171
+ end
172
+ end
173
+ end
174
+
175
+ context "but `os_version:` is not given" do
176
+ it do
177
+ expect {
178
+ subject.build(chrome_version: chrome_version, os: os)
179
+ }.to raise_error(ArgumentError,"os: #{os.inspect} also requires an os_version: value")
180
+ end
181
+ end
182
+ end
183
+
184
+ context "when given `os: :linux`" do
185
+ let(:os) { :linux }
186
+
187
+ context "but `arch:` is not given" do
188
+ it do
189
+ expect {
190
+ subject.build(chrome_version: chrome_version, os: os)
191
+ }.to raise_error(ArgumentError,"os: #{os.inspect} also requires an arch: value")
192
+ end
193
+ end
194
+
195
+ Ronin::Web::UserAgents::OS::Linux::ARCHES.each do |arch_id,arch_string|
196
+ context "when given `arch: #{arch_id.inspect}`" do
197
+ let(:arch) { arch_id }
198
+ let(:linux_arch) { arch_string }
199
+
200
+ it "must add 'Linux #{arch_string}' to the extensions" do
201
+ expect(
202
+ subject.build(
203
+ chrome_version: chrome_version,
204
+ os: os,
205
+ arch: arch
206
+ )
207
+ ).to eq("Mozilla/5.0 (X11; Linux #{linux_arch}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Safari/537.36")
208
+ end
209
+
210
+ Ronin::Web::UserAgents::OS::Linux::DISTROS.each do |distro_id,distro_string|
211
+ context "and when given `linux_distro: #{distro_id.inspect}" do
212
+ if distro_id
213
+ let(:linux_distro) { distro_string }
214
+
215
+ it "must add the '; #{distro_string}' to the extensions" do
216
+ expect(
217
+ subject.build(
218
+ chrome_version: chrome_version,
219
+ os: os,
220
+ linux_distro: linux_distro,
221
+ arch: arch
222
+ )
223
+ ).to eq("Mozilla/5.0 (X11; #{linux_distro}; Linux #{linux_arch}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Safari/537.36")
224
+ end
225
+ else # `linux_distro: nil` edge-case
226
+ it "must omit the Linux Distro from the extensions" do
227
+ expect(
228
+ subject.build(
229
+ chrome_version: chrome_version,
230
+ os: os,
231
+ arch: arch
232
+ )
233
+ ).to eq("Mozilla/5.0 (X11; Linux #{linux_arch}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Safari/537.36")
234
+ end
235
+ end
236
+ end
237
+ end
238
+
239
+ context "and when given the `chrome_version:` keyword argument" do
240
+ let(:chrome_version) { '1.2.3' }
241
+
242
+ it "must use the specified `chrome_version:` value" do
243
+ expect(
244
+ subject.build(
245
+ chrome_version: chrome_version,
246
+ os: os,
247
+ arch: arch
248
+ )
249
+ ).to eq("Mozilla/5.0 (X11; Linux #{linux_arch}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Safari/537.36")
250
+ end
251
+ end
252
+ end
253
+ end
254
+ end
255
+
256
+ context "when given `os: :android`" do
257
+ let(:os) { :android }
258
+
259
+ context "but os_version: is not given" do
260
+ it do
261
+ expect {
262
+ subject.build(chrome_version: chrome_version, os: os)
263
+ }.to raise_error(ArgumentError,"os: #{os.inspect} also requires an os_version: value")
264
+ end
265
+ end
266
+
267
+ context "when given an `os_version:` keyword argument" do
268
+ let(:os_version) { '4.0.4' }
269
+ let(:android_version) { os_version }
270
+
271
+ it "must add 'Linux; Android ...' to the extensions" do
272
+ expect(
273
+ subject.build(
274
+ chrome_version: chrome_version,
275
+ os: os,
276
+ os_version: os_version
277
+ )
278
+ ).to eq("Mozilla/5.0 (Linux; Android #{android_version}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Mobile Safari/537.36")
279
+ end
280
+
281
+ Ronin::Web::UserAgents::OS::Android::ARCHES.each do |arch_id,arch_string|
282
+ context "and when given `arch: #{arch_id.inspect}`" do
283
+ let(:arch) { arch_id }
284
+ let(:android_arch) { arch_string }
285
+
286
+ if arch_id
287
+ it "must add 'Linux; #{arch_string}' to the extensions" do
288
+ expect(
289
+ subject.build(
290
+ chrome_version: chrome_version,
291
+ os: os,
292
+ os_version: os_version,
293
+ arch: arch
294
+ )
295
+ ).to eq("Mozilla/5.0 (Linux; #{android_arch}; Android #{android_version}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Mobile Safari/537.36")
296
+ end
297
+
298
+ context "and when given `chrome_version: ...`" do
299
+ let(:chrome_version) { '1.2.3' }
300
+
301
+ it "must use the specified `chrome_version:` value" do
302
+ expect(
303
+ subject.build(
304
+ chrome_version: chrome_version,
305
+ os: os,
306
+ os_version: os_version,
307
+ arch: arch
308
+ )
309
+ ).to eq("Mozilla/5.0 (Linux; #{android_arch}; Android #{android_version}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Mobile Safari/537.36")
310
+ end
311
+ end
312
+ else # `arch: nil` edge-case
313
+ it "must omit th Android architecture from the extensions" do
314
+ expect(
315
+ subject.build(
316
+ chrome_version: chrome_version,
317
+ os: os,
318
+ os_version: os_version,
319
+ arch: arch
320
+ )
321
+ ).to eq("Mozilla/5.0 (Linux; Android #{android_version}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Mobile Safari/537.36")
322
+ end
323
+
324
+ context "and when given the `chrome_version:` keyword argument" do
325
+ let(:chrome_version) { '1.2.3' }
326
+
327
+ it "must use the specified `chrome_version:` value" do
328
+ expect(
329
+ subject.build(
330
+ chrome_version: chrome_version,
331
+ os: os,
332
+ os_version: os_version,
333
+ arch: arch
334
+ )
335
+ ).to eq("Mozilla/5.0 (Linux; Android #{android_version}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Mobile Safari/537.36")
336
+ end
337
+ end
338
+ end
339
+ end
340
+ end
341
+
342
+ context "when the `android_device:` keyword argument is given" do
343
+ let(:android_device) { 'SM-A307FN' }
344
+
345
+ it "must include the Android device in the extensions" do
346
+ expect(
347
+ subject.build(
348
+ chrome_version: chrome_version,
349
+ os: os,
350
+ os_version: os_version,
351
+ android_device: android_device
352
+ )
353
+ ).to eq("Mozilla/5.0 (Linux; Android #{android_version}; #{android_device}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/#{chrome_version} Mobile Safari/537.36")
354
+ end
355
+ end
356
+ end
357
+ end
358
+
359
+ context "when given `os: :other`" do
360
+ let(:os) { :other }
361
+
362
+ it do
363
+ expect {
364
+ subject.build(chrome_version: chrome_version, os: os)
365
+ }.to raise_error(ArgumentError,"unsupported os: value (#{os.inspect})")
366
+ end
367
+ end
368
+ end
369
+
370
+ describe ".random" do
371
+ it "must return a random Chrome User-Agent string" do
372
+ expect(subject.random).to match(
373
+ %r{^Mozilla/5\.0 \([^\)]+\) AppleWebKit/537\.36 \(KHTML, like Gecko\) Chrome/\d+(\.\d+)* (?:Mobile )?Safari/537\.36$}
374
+ )
375
+ end
376
+
377
+ it "must generate a new random Chrome User-Agent string each time" do
378
+ expect(subject.random).to_not eq(subject.random)
379
+ end
380
+
381
+ context "when `os: :windows`" do
382
+ let(:os) { :windows }
383
+
384
+ it "must return a random Windows Chrome User-Agent string" do
385
+ expect(subject.random(os: os)).to match(
386
+ %r{^Mozilla/5\.0 \(Windows NT \d+(?:\.\d+)*(?:; (?:WOW64|Win64; x64))?\) AppleWebKit/537\.36 \(KHTML, like Gecko\) Chrome/\d+(\.\d+)* (?:Mobile )?Safari/537\.36$}
387
+ )
388
+ end
389
+
390
+ context "and when given `os_version:`" do
391
+ let(:os_version) { 10 }
392
+
393
+ it "must return a random Windows Chrome User-Agent string for that version of Windows" do
394
+ expect(subject.random(os: os, os_version: os_version)).to match(
395
+ %r{^Mozilla/5\.0 \(Windows NT 10\.0(?:; (?:WOW64|Win64; x64))?\) AppleWebKit/537\.36 \(KHTML, like Gecko\) Chrome/\d+(\.\d+)* (?:Mobile )?Safari/537\.36$}
396
+ )
397
+ end
398
+ end
399
+
400
+ context "and when given `arch: :wow64`" do
401
+ let(:arch) { :wow64 }
402
+
403
+ it "must return a random Windows Chrome User-Agent string for the WOW64 architecture" do
404
+ expect(subject.random(os: os, arch: arch)).to match(
405
+ %r{^Mozilla/5\.0 \(Windows NT \d+(?:\.\d+)*; WOW64\) AppleWebKit/537\.36 \(KHTML, like Gecko\) Chrome/\d+(\.\d+)* (?:Mobile )?Safari/537\.36$}
406
+ )
407
+ end
408
+ end
409
+
410
+ context "and when given `arch: :win64`" do
411
+ let(:arch) { :win64 }
412
+
413
+ it "must return a random Windows Chrome User-Agent string for the WOW64 architecture" do
414
+ expect(subject.random(os: os, arch: arch)).to match(
415
+ %r{^Mozilla/5\.0 \(Windows NT \d+(?:\.\d+)*; Win64; x64\) AppleWebKit/537\.36 \(KHTML, like Gecko\) Chrome/\d+(\.\d+)* (?:Mobile )?Safari/537\.36$}
416
+ )
417
+ end
418
+ end
419
+ end
420
+
421
+ context "when `os: :macos` is given" do
422
+ let(:os) { :macos }
423
+
424
+ it "must return a macOS Chrome User-Agent string" do
425
+ expect(subject.random(os: os)).to match(
426
+ %r{^Mozilla/5\.0 \(Macintosh; Intel Mac OS X \d+(_\d+){1,2}\) AppleWebKit/537\.36 \(KHTML, like Gecko\) Chrome/\d+(\.\d+)* (?:Mobile )?Safari/537\.36$}
427
+ )
428
+ end
429
+
430
+ context "and when `os_version:` is given" do
431
+ let(:os_version) { '10.11.12' }
432
+
433
+ it "must return a macOS Chrome User-Agent string for that macOS version" do
434
+ expect(subject.random(os: os, os_version: os_version)).to match(
435
+ %r{^Mozilla/5\.0 \(Macintosh; Intel Mac OS X 10_11_12\) AppleWebKit/537\.36 \(KHTML, like Gecko\) Chrome/\d+(\.\d+)* (?:Mobile )?Safari/537\.36$}
436
+ )
437
+ end
438
+ end
439
+ end
440
+
441
+ context "when `os: :linux` is given" do
442
+ let(:os) { :linux }
443
+
444
+ it "must return a Linux Chrome User-Agent string" do
445
+ expect(subject.random(os: os)).to match(
446
+ %r{^Mozilla/5\.0 \(X11(?:; (?:Ubuntu|Fedora|Arch))?; Linux (?:x86_64|aarch64|i686)\) AppleWebKit/537\.36 \(KHTML, like Gecko\) Chrome/\d+(\.\d+)* (?:Mobile )?Safari/537\.36$}
447
+ )
448
+ end
449
+
450
+ context "and when `linux_distro:` is given" do
451
+ let(:linux_distro) { :ubuntu }
452
+
453
+ it "must return a Linux Chrome User-Agent string for that Linux Distro" do
454
+ expect(subject.random(os: os, linux_distro: linux_distro)).to match(
455
+ %r{^Mozilla/5\.0 \(X11; Ubuntu; Linux (?:x86_64|aarch64|i686)\) AppleWebKit/537\.36 \(KHTML, like Gecko\) Chrome/\d+(\.\d+)* (?:Mobile )?Safari/537\.36$}
456
+ )
457
+ end
458
+ end
459
+
460
+ context "and when `arch:` is given" do
461
+ let(:arch) { :arm64 }
462
+
463
+ it "must return a Linux Chrome User-Agent string for that architecture" do
464
+ expect(subject.random(os: os, arch: arch)).to match(
465
+ %r{^Mozilla/5\.0 \(X11(?:; (?:Ubuntu|Fedora|Arch))?; Linux aarch64\) AppleWebKit/537\.36 \(KHTML, like Gecko\) Chrome/\d+(\.\d+)* (?:Mobile )?Safari/537\.36$}
466
+ )
467
+ end
468
+ end
469
+ end
470
+
471
+ context "when `os: :android` is given" do
472
+ let(:os) { :android }
473
+
474
+ it "must return a Android Chrome User-Agent string" do
475
+ expect(subject.random(os: os)).to match(
476
+ %r{^Mozilla/5\.0 \(Linux(?:; (?:arm|arm_64))?; Android \d+(?:\.\d+)*(?:; [^\(\)]+(?:\([^\)]+\)[^\(\)]+)?)?\) AppleWebKit/537\.36 \(KHTML, like Gecko\) Chrome/\d+(\.\d+)* (?:Mobile )?Safari/537\.36$}
477
+ )
478
+ end
479
+
480
+ context "and when `os_version:` is given" do
481
+ let(:os_version) { '8.1' }
482
+
483
+ it "must return a Android Chrome User-Agent string for that Android version" do
484
+ expect(subject.random(os: os, os_version: os_version)).to match(
485
+ %r{^Mozilla/5\.0 \(Linux(?:; (?:arm|arm_64))?; Android 8\.1(?:; [^\(\)]+(?:\([^\)]+\)[^\(\)]+)?)?\) AppleWebKit/537\.36 \(KHTML, like Gecko\) Chrome/\d+(\.\d+)* (?:Mobile )?Safari/537\.36$}
486
+ )
487
+ end
488
+ end
489
+
490
+ context "and when `arch:` is given" do
491
+ let(:arch) { :arm64 }
492
+
493
+ it "must return a Linux Chrome User-Agent string for that architecture" do
494
+ expect(subject.random(os: os, arch: arch)).to match(
495
+ %r{^Mozilla/5\.0 \(Linux; arm_64; Android (?:\d+(?:\.\d+)*)(?:; [^\(\)]+(?:\([^\)]+\)[^\(\)]+)?)?\) AppleWebKit/537\.36 \(KHTML, like Gecko\) Chrome/\d+(\.\d+)* (?:Mobile )?Safari/537\.36$}
496
+ )
497
+ end
498
+ end
499
+
500
+ context "and when `android_device:` is given" do
501
+ let(:android_device) { 'SM-A307FN' }
502
+
503
+ it "must return a Linux Chrome User-Agent string with that Android device" do
504
+ expect(subject.random(os: os, android_device: android_device)).to match(
505
+ %r{^Mozilla/5\.0 \(Linux(?:; (?:arm|arm_64))?; Android (?:\d+(?:\.\d+)*); #{android_device}\) AppleWebKit/537\.36 \(KHTML, like Gecko\) Chrome/\d+(\.\d+)* (?:Mobile )?Safari/537\.36$}
506
+ )
507
+ end
508
+ end
509
+ end
510
+ end
511
+ end