arachni 1.2.1 → 1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (373) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -0
  3. data/Gemfile +1 -1
  4. data/README.md +16 -5
  5. data/components/checks/active/ldap_injection/errors.txt +1 -0
  6. data/components/checks/active/source_code_disclosure.rb +1 -1
  7. data/components/checks/active/unvalidated_redirect.rb +6 -6
  8. data/components/checks/active/unvalidated_redirect_dom.rb +10 -7
  9. data/components/checks/passive/grep/captcha.rb +14 -5
  10. data/components/checks/passive/grep/form_upload.rb +7 -3
  11. data/components/checks/passive/grep/hsts.rb +3 -3
  12. data/components/checks/passive/grep/html_objects.rb +2 -3
  13. data/components/checks/passive/grep/http_only_cookies.rb +2 -3
  14. data/components/checks/passive/grep/insecure_cookies.rb +1 -1
  15. data/components/checks/passive/grep/password_autocomplete.rb +2 -2
  16. data/components/checks/passive/grep/unencrypted_password_forms.rb +7 -7
  17. data/components/checks/passive/grep/x_frame_options.rb +2 -2
  18. data/components/checks/passive/http_put.rb +2 -3
  19. data/components/path_extractors/comments.rb +3 -3
  20. data/components/path_extractors/scripts.rb +10 -1
  21. data/components/plugins/defaults/autothrottle.rb +27 -18
  22. data/components/plugins/defaults/meta/remedies/discovery.rb +30 -33
  23. data/components/plugins/defaults/meta/remedies/timing_attacks.rb +7 -11
  24. data/components/plugins/login_script.rb +9 -3
  25. data/components/plugins/proxy.rb +4 -3
  26. data/components/reporters/html.rb +11 -14
  27. data/components/reporters/html/default/issue.erb +13 -38
  28. data/components/reporters/html/default/issue/info.erb +1 -1
  29. data/components/reporters/html/default/summary/issues/by_name.erb +3 -3
  30. data/components/reporters/stdout.rb +62 -71
  31. data/components/reporters/xml.rb +26 -40
  32. data/components/reporters/xml/schema.xsd +43 -89
  33. data/lib/arachni/browser.rb +52 -3
  34. data/lib/arachni/browser/javascript.rb +3 -3
  35. data/lib/arachni/browser/javascript/scripts/taint_tracer.js +46 -25
  36. data/lib/arachni/browser_cluster.rb +61 -0
  37. data/lib/arachni/browser_cluster/job.rb +21 -1
  38. data/lib/arachni/browser_cluster/jobs/browser_provider.rb +3 -1
  39. data/lib/arachni/browser_cluster/jobs/resource_exploration.rb +2 -1
  40. data/lib/arachni/browser_cluster/jobs/resource_exploration/event_trigger.rb +2 -1
  41. data/lib/arachni/browser_cluster/jobs/taint_trace.rb +3 -2
  42. data/lib/arachni/browser_cluster/jobs/taint_trace/event_trigger.rb +1 -1
  43. data/lib/arachni/browser_cluster/worker.rb +5 -0
  44. data/lib/arachni/check/auditor.rb +22 -12
  45. data/lib/arachni/data/framework.rb +13 -1
  46. data/lib/arachni/data/issues.rb +9 -25
  47. data/lib/arachni/element/base.rb +9 -3
  48. data/lib/arachni/element/capabilities/analyzable.rb +2 -6
  49. data/lib/arachni/element/capabilities/analyzable/differential.rb +24 -7
  50. data/lib/arachni/element/capabilities/analyzable/{taint.rb → signature.rb} +23 -23
  51. data/lib/arachni/element/capabilities/auditable.rb +0 -6
  52. data/lib/arachni/element/capabilities/dom_only.rb +61 -0
  53. data/lib/arachni/element/capabilities/with_dom.rb +3 -1
  54. data/lib/arachni/element/cookie.rb +35 -5
  55. data/lib/arachni/element/cookie/dom.rb +13 -4
  56. data/lib/arachni/element/{capabilities/auditable/dom.rb → dom.rb} +20 -68
  57. data/lib/arachni/element/dom/capabilities/auditable.rb +29 -0
  58. data/lib/arachni/element/dom/capabilities/inputtable.rb +27 -0
  59. data/lib/arachni/element/dom/capabilities/mutable.rb +21 -0
  60. data/lib/arachni/element/dom/capabilities/submittable.rb +52 -0
  61. data/lib/arachni/element/form.rb +12 -1
  62. data/lib/arachni/element/form/capabilities/mutable.rb +2 -1
  63. data/lib/arachni/element/form/capabilities/with_dom.rb +0 -1
  64. data/lib/arachni/element/form/dom.rb +9 -3
  65. data/lib/arachni/element/header.rb +14 -33
  66. data/lib/arachni/element/header/capabilities/inputtable.rb +29 -0
  67. data/lib/arachni/element/header/capabilities/mutable.rb +51 -0
  68. data/lib/arachni/element/input/dom.rb +71 -0
  69. data/lib/arachni/element/json.rb +2 -0
  70. data/lib/arachni/element/link.rb +3 -0
  71. data/lib/arachni/element/link/capabilities/with_dom.rb +0 -1
  72. data/lib/arachni/element/link/dom.rb +16 -3
  73. data/lib/arachni/element/link/dom/capabilities/submittable.rb +29 -0
  74. data/lib/arachni/element/link_template.rb +3 -5
  75. data/lib/arachni/element/link_template/capabilities/inputtable.rb +5 -0
  76. data/lib/arachni/element/link_template/capabilities/with_dom.rb +0 -1
  77. data/lib/arachni/element/link_template/dom.rb +16 -3
  78. data/lib/arachni/element/link_template/dom/capabilities/submittable.rb +29 -0
  79. data/lib/arachni/element/server.rb +3 -5
  80. data/lib/arachni/element/ui_form.rb +106 -0
  81. data/lib/arachni/element/ui_form/dom.rb +107 -0
  82. data/lib/arachni/element/ui_input.rb +62 -0
  83. data/lib/arachni/element/xml.rb +2 -1
  84. data/lib/arachni/framework.rb +7 -5
  85. data/lib/arachni/framework/parts/audit.rb +0 -1
  86. data/lib/arachni/framework/parts/check.rb +1 -0
  87. data/lib/arachni/framework/parts/data.rb +4 -0
  88. data/lib/arachni/framework/parts/state.rb +0 -2
  89. data/lib/arachni/http/client.rb +17 -6
  90. data/lib/arachni/http/proxy_server.rb +52 -5
  91. data/lib/arachni/http/request.rb +1 -1
  92. data/lib/arachni/issue.rb +34 -179
  93. data/lib/arachni/issue/severity.rb +2 -0
  94. data/lib/arachni/option_groups/audit.rb +22 -2
  95. data/lib/arachni/option_groups/browser_cluster.rb +15 -0
  96. data/lib/arachni/page.rb +3 -2
  97. data/lib/arachni/parser.rb +24 -5
  98. data/lib/arachni/platform/manager.rb +1 -2
  99. data/lib/arachni/rpc/server/framework.rb +3 -4
  100. data/lib/arachni/rpc/server/framework/multi_instance.rb +2 -1
  101. data/lib/arachni/session.rb +1 -1
  102. data/lib/arachni/trainer.rb +4 -7
  103. data/lib/arachni/watir/element.rb +12 -1
  104. data/lib/version +1 -1
  105. data/spec/arachni/browser/element_locator_spec.rb +43 -43
  106. data/spec/arachni/browser/javascript/dom_monitor_spec.rb +44 -44
  107. data/spec/arachni/browser/javascript/proxy/stub_spec.rb +17 -14
  108. data/spec/arachni/browser/javascript/proxy_spec.rb +24 -24
  109. data/spec/arachni/browser/javascript/taint_tracer/frame/called_function_spec.rb +11 -11
  110. data/spec/arachni/browser/javascript/taint_tracer/frame_spec.rb +7 -7
  111. data/spec/arachni/browser/javascript/taint_tracer/sink/data_flow_spec.rb +13 -13
  112. data/spec/arachni/browser/javascript/taint_tracer/sink/execution_flow_spec.rb +7 -7
  113. data/spec/arachni/browser/javascript/taint_tracer_spec.rb +568 -558
  114. data/spec/arachni/browser/javascript_spec.rb +73 -63
  115. data/spec/arachni/browser_cluster/job/result_spec.rb +3 -3
  116. data/spec/arachni/browser_cluster/job_spec.rb +68 -48
  117. data/spec/arachni/browser_cluster/jobs/resource_exploration/event_trigger/result_spec.rb +2 -2
  118. data/spec/arachni/browser_cluster/jobs/resource_exploration/event_trigger_spec.rb +5 -4
  119. data/spec/arachni/browser_cluster/jobs/resource_exploration/result_spec.rb +2 -2
  120. data/spec/arachni/browser_cluster/jobs/resource_exploration_spec.rb +5 -5
  121. data/spec/arachni/browser_cluster/worker_spec.rb +87 -70
  122. data/spec/arachni/browser_cluster_spec.rb +64 -39
  123. data/spec/arachni/browser_spec.rb +692 -527
  124. data/spec/arachni/check/auditor_spec.rb +177 -147
  125. data/spec/arachni/check/base_spec.rb +33 -33
  126. data/spec/arachni/check/manager_spec.rb +15 -15
  127. data/spec/arachni/component/base_spec.rb +8 -8
  128. data/spec/arachni/component/manager_spec.rb +100 -99
  129. data/spec/arachni/component/options/address_spec.rb +3 -3
  130. data/spec/arachni/component/options/base_spec.rb +7 -7
  131. data/spec/arachni/component/options/bool_spec.rb +9 -9
  132. data/spec/arachni/component/options/float_spec.rb +6 -6
  133. data/spec/arachni/component/options/int_spec.rb +5 -5
  134. data/spec/arachni/component/options/multiple_choice_spec.rb +12 -12
  135. data/spec/arachni/component/options/object_spec.rb +2 -2
  136. data/spec/arachni/component/options/path_spec.rb +3 -3
  137. data/spec/arachni/component/options/port_spec.rb +5 -5
  138. data/spec/arachni/component/options/string_spec.rb +3 -3
  139. data/spec/arachni/component/options/url_spec.rb +4 -4
  140. data/spec/arachni/component/utilities_spec.rb +2 -2
  141. data/spec/arachni/data/framework/rpc_spec.rb +10 -9
  142. data/spec/arachni/data/framework_spec.rb +65 -46
  143. data/spec/arachni/data/issues_spec.rb +39 -77
  144. data/spec/arachni/data/plugins_spec.rb +11 -11
  145. data/spec/arachni/data/session_spec.rb +6 -6
  146. data/spec/arachni/data_spec.rb +8 -8
  147. data/spec/arachni/element/body_spec.rb +10 -10
  148. data/spec/arachni/element/capabilities/analyzable/differential_spec.rb +39 -21
  149. data/spec/arachni/element/capabilities/analyzable/{taint_spec.rb → signature_spec.rb} +63 -63
  150. data/spec/arachni/element/capabilities/analyzable/timeout_spec.rb +51 -51
  151. data/spec/arachni/element/capabilities/with_scope/scope_spec.rb +5 -5
  152. data/spec/arachni/element/cookie/dom_spec.rb +37 -18
  153. data/spec/arachni/element/cookie_spec.rb +206 -139
  154. data/spec/arachni/element/form/dom_spec.rb +36 -19
  155. data/spec/arachni/element/form_spec.rb +210 -187
  156. data/spec/arachni/element/generic_dom_spec.rb +14 -14
  157. data/spec/arachni/element/header_spec.rb +35 -17
  158. data/spec/arachni/element/json_spec.rb +53 -31
  159. data/spec/arachni/element/link/dom_spec.rb +46 -28
  160. data/spec/arachni/element/link_spec.rb +58 -40
  161. data/spec/arachni/element/link_template/dom_spec.rb +47 -29
  162. data/spec/arachni/element/link_template_spec.rb +79 -61
  163. data/spec/arachni/element/path_spec.rb +1 -1
  164. data/spec/arachni/element/server_spec.rb +33 -32
  165. data/spec/arachni/element/ui_form/ui_form_dom_spec.rb +164 -0
  166. data/spec/arachni/element/ui_form_spec.rb +242 -0
  167. data/spec/arachni/element/ui_input/dom_spec.rb +157 -0
  168. data/spec/arachni/element/ui_input_spec.rb +136 -0
  169. data/spec/arachni/element/xml_spec.rb +42 -24
  170. data/spec/arachni/element_filter_spec.rb +49 -48
  171. data/spec/arachni/error_spec.rb +3 -3
  172. data/spec/arachni/framework/parts/audit_spec.rb +64 -63
  173. data/spec/arachni/framework/parts/browser_spec.rb +16 -16
  174. data/spec/arachni/framework/parts/check_spec.rb +3 -3
  175. data/spec/arachni/framework/parts/data_spec.rb +48 -48
  176. data/spec/arachni/framework/parts/platform_spec.rb +3 -3
  177. data/spec/arachni/framework/parts/plugin_spec.rb +7 -6
  178. data/spec/arachni/framework/parts/report_spec.rb +7 -7
  179. data/spec/arachni/framework/parts/scope_spec.rb +16 -16
  180. data/spec/arachni/framework/parts/state_spec.rb +68 -69
  181. data/spec/arachni/framework_spec.rb +39 -31
  182. data/spec/arachni/http/client/dynamic_404_handlers_spec.rb +32 -32
  183. data/spec/arachni/http/client_spec.rb +219 -208
  184. data/spec/arachni/http/cookie_jar_spec.rb +72 -72
  185. data/spec/arachni/http/headers_spec.rb +14 -14
  186. data/spec/arachni/http/proxy_server_spec.rb +43 -42
  187. data/spec/arachni/http/request_spec.rb +105 -103
  188. data/spec/arachni/http/response/scope_spec.rb +24 -24
  189. data/spec/arachni/http/response_spec.rb +50 -49
  190. data/spec/arachni/issue/severity_spec.rb +10 -9
  191. data/spec/arachni/issue_spec.rb +71 -369
  192. data/spec/arachni/option_groups/audit_spec.rb +114 -114
  193. data/spec/arachni/option_groups/browser_cluster_spec.rb +20 -3
  194. data/spec/arachni/option_groups/datastore_spec.rb +6 -6
  195. data/spec/arachni/option_groups/dispatcher_spec.rb +19 -19
  196. data/spec/arachni/option_groups/http_spec.rb +11 -11
  197. data/spec/arachni/option_groups/input_spec.rb +31 -27
  198. data/spec/arachni/option_groups/output_spec.rb +2 -2
  199. data/spec/arachni/option_groups/paths_spec.rb +17 -17
  200. data/spec/arachni/option_groups/rpc_spec.rb +2 -2
  201. data/spec/arachni/option_groups/scope_spec.rb +40 -40
  202. data/spec/arachni/option_groups/session_spec.rb +6 -5
  203. data/spec/arachni/option_groups/snapshot_spec.rb +4 -4
  204. data/spec/arachni/options_spec.rb +46 -45
  205. data/spec/arachni/page/dom/transition_spec.rb +74 -72
  206. data/spec/arachni/page/dom_spec.rb +35 -35
  207. data/spec/arachni/page/scope_spec.rb +15 -15
  208. data/spec/arachni/page_spec.rb +217 -217
  209. data/spec/arachni/parser_spec.rb +106 -104
  210. data/spec/arachni/platform/fingerprinter_spec.rb +17 -14
  211. data/spec/arachni/platform/list_spec.rb +33 -33
  212. data/spec/arachni/platform/manager_spec.rb +67 -64
  213. data/spec/arachni/plugin/base_spec.rb +10 -10
  214. data/spec/arachni/plugin/manager_spec.rb +38 -37
  215. data/spec/arachni/report_spec.rb +43 -40
  216. data/spec/arachni/reporter/base_spec.rb +15 -15
  217. data/spec/arachni/reporter/manager_spec.rb +4 -4
  218. data/spec/arachni/reporter/options_spec.rb +6 -6
  219. data/spec/arachni/rpc/client/base_spec.rb +6 -6
  220. data/spec/arachni/rpc/client/dispatcher_spec.rb +2 -2
  221. data/spec/arachni/rpc/client/instance_spec.rb +6 -6
  222. data/spec/arachni/rpc/server/active_options_spec.rb +11 -8
  223. data/spec/arachni/rpc/server/base_spec.rb +5 -5
  224. data/spec/arachni/rpc/server/checks/manager_spec.rb +8 -8
  225. data/spec/arachni/rpc/server/dispatcher/node_spec.rb +37 -37
  226. data/spec/arachni/rpc/server/dispatcher/service_spec.rb +15 -14
  227. data/spec/arachni/rpc/server/dispatcher_spec.rb +36 -35
  228. data/spec/arachni/rpc/server/framework/distributor_spec.rb +36 -36
  229. data/spec/arachni/rpc/server/framework_multi_spec.rb +340 -336
  230. data/spec/arachni/rpc/server/framework_spec.rb +90 -85
  231. data/spec/arachni/rpc/server/instance_spec.rb +126 -107
  232. data/spec/arachni/rpc/server/output_spec.rb +1 -1
  233. data/spec/arachni/rpc/server/plugin/manager_spec.rb +6 -6
  234. data/spec/arachni/ruby/array_spec.rb +42 -42
  235. data/spec/arachni/ruby/hash_spec.rb +20 -18
  236. data/spec/arachni/ruby/io_spec.rb +2 -2
  237. data/spec/arachni/ruby/object_spec.rb +1 -1
  238. data/spec/arachni/ruby/set_spec.rb +3 -3
  239. data/spec/arachni/ruby/string_spec.rb +30 -30
  240. data/spec/arachni/ruby/webrick_spec.rb +2 -2
  241. data/spec/arachni/scope_spec.rb +1 -1
  242. data/spec/arachni/session_spec.rb +67 -64
  243. data/spec/arachni/snapshot_spec.rb +15 -15
  244. data/spec/arachni/state/audit_spec.rb +11 -11
  245. data/spec/arachni/state/element_filter_spec.rb +6 -6
  246. data/spec/arachni/state/framework/rpc_spec.rb +12 -12
  247. data/spec/arachni/state/framework_spec.rb +125 -121
  248. data/spec/arachni/state/http_spec.rb +7 -7
  249. data/spec/arachni/state/options_spec.rb +7 -7
  250. data/spec/arachni/state/plugins_spec.rb +8 -8
  251. data/spec/arachni/state_spec.rb +10 -10
  252. data/spec/arachni/support/buffer/autoflush_spec.rb +16 -16
  253. data/spec/arachni/support/buffer/base_spec.rb +39 -39
  254. data/spec/arachni/support/cache/least_cost_replacement_spec.rb +18 -18
  255. data/spec/arachni/support/cache/least_recently_pushed_spec.rb +24 -24
  256. data/spec/arachni/support/cache/least_recently_used_spec.rb +20 -20
  257. data/spec/arachni/support/cache/preference_spec.rb +4 -4
  258. data/spec/arachni/support/cache/random_replacement_spec.rb +8 -8
  259. data/spec/arachni/support/crypto/rsa_aes_cbc_spec.rb +1 -1
  260. data/spec/arachni/support/database/hash_spec.rb +44 -43
  261. data/spec/arachni/support/database/queue_spec.rb +27 -27
  262. data/spec/arachni/support/lookup/hash_set_spec.rb +8 -8
  263. data/spec/arachni/support/lookup/moolb_spec.rb +3 -3
  264. data/spec/arachni/support/mixins/observable_spec.rb +6 -6
  265. data/spec/arachni/support/signature_spec.rb +19 -19
  266. data/spec/arachni/trainer_spec.rb +39 -39
  267. data/spec/arachni/typhoeus/hydra_spec.rb +2 -2
  268. data/spec/arachni/uri/scope_spec.rb +66 -66
  269. data/spec/arachni/uri_spec.rb +107 -105
  270. data/spec/arachni/utilities_spec.rb +40 -40
  271. data/spec/components/checks/active/csrf_spec.rb +8 -8
  272. data/spec/components/checks/active/no_sql_injection_spec.rb +1 -1
  273. data/spec/components/checks/active/sql_injection_spec.rb +16 -16
  274. data/spec/components/checks/active/trainer_spec.rb +4 -4
  275. data/spec/components/checks/active/unvalidated_redirect_dom_spec.rb +4 -2
  276. data/spec/components/checks/active/xpath_injection_spec.rb +1 -1
  277. data/spec/components/checks/active/xss_dom_script_context_spec.rb +51 -21
  278. data/spec/components/checks/active/xss_dom_spec.rb +46 -24
  279. data/spec/components/checks/passive/allowed_methods_spec.rb +1 -1
  280. data/spec/components/checks/passive/grep/cookie_set_for_parent_domain_spec.rb +1 -1
  281. data/spec/components/checks/passive/grep/hsts_spec.rb +2 -2
  282. data/spec/components/checks/passive/grep/http_only_cookies_spec.rb +1 -1
  283. data/spec/components/checks/passive/grep/insecure_cookies_spec.rb +1 -1
  284. data/spec/components/checks/passive/grep/insecure_cors_policy_spec.rb +2 -2
  285. data/spec/components/checks/passive/grep/password_autocomplete_spec.rb +1 -1
  286. data/spec/components/checks/passive/grep/private_ip_spec.rb +3 -3
  287. data/spec/components/checks/passive/grep/unencrypted_password_forms_spec.rb +1 -1
  288. data/spec/components/checks/passive/grep/x_frame_options_spec.rb +2 -2
  289. data/spec/components/checks/passive/interesting_responses_spec.rb +2 -2
  290. data/spec/components/checks/passive/webdav_spec.rb +1 -1
  291. data/spec/components/checks/passive/xst_spec.rb +1 -1
  292. data/spec/components/fingerprinters/servers/apache_spec.rb +2 -2
  293. data/spec/components/path_extractors/comments_spec.rb +5 -1
  294. data/spec/components/path_extractors/scripts_spec.rb +5 -2
  295. data/spec/components/plugins/autologin_spec.rb +22 -22
  296. data/spec/components/plugins/autothrottle_spec.rb +6 -5
  297. data/spec/components/plugins/content_types_spec.rb +4 -4
  298. data/spec/components/plugins/cookie_collector_spec.rb +5 -5
  299. data/spec/components/plugins/exec_spec.rb +12 -12
  300. data/spec/components/plugins/form_dicattack_spec.rb +3 -3
  301. data/spec/components/plugins/headers_collector_spec.rb +8 -8
  302. data/spec/components/plugins/healthmap_spec.rb +3 -3
  303. data/spec/components/plugins/http_dicattack_spec.rb +3 -3
  304. data/spec/components/plugins/login_script_spec.rb +79 -22
  305. data/spec/components/plugins/meta/remedies/discovery_spec.rb +3 -2
  306. data/spec/components/plugins/meta/remedies/timing_attacks_spec.rb +3 -3
  307. data/spec/components/plugins/meta/uniformity_spec.rb +2 -2
  308. data/spec/components/plugins/restrict_to_dom_state_spec.rb +1 -1
  309. data/spec/components/plugins/script_spec.rb +1 -1
  310. data/spec/components/plugins/uncommon_headers_spec.rb +2 -2
  311. data/spec/components/plugins/vector_collector_spec.rb +2 -2
  312. data/spec/components/plugins/vector_feed_spec.rb +40 -40
  313. data/spec/components/plugins/waf_detector_spec.rb +6 -6
  314. data/spec/components/reporters/json_spec.rb +4 -4
  315. data/spec/components/reporters/marshal_spec.rb +2 -2
  316. data/spec/components/reporters/yaml_spec.rb +3 -2
  317. data/spec/external/wavsep/active/sqli_spec.rb +1 -3
  318. data/spec/spec_helper.rb +4 -0
  319. data/spec/support/factories/element/ui_form.rb +14 -0
  320. data/spec/support/factories/element/ui_input.rb +13 -0
  321. data/spec/support/factories/issue.rb +0 -13
  322. data/spec/support/fixtures/report.afr +0 -0
  323. data/spec/support/fixtures/{taint_check/taint.rb → signature_check/signature.rb} +2 -2
  324. data/spec/support/helpers/browser_cluster/jobs/taint_tracer.rb +11 -11
  325. data/spec/support/helpers/framework.rb +1 -1
  326. data/spec/support/helpers/pages.rb +2 -2
  327. data/spec/support/servers/arachni/browser.rb +139 -0
  328. data/spec/support/servers/arachni/browser/javascript/taint_tracer.rb +40 -0
  329. data/spec/support/servers/arachni/element/capabilities/analyzable/{taint.rb → signature.rb} +0 -0
  330. data/spec/support/servers/arachni/element/input/input_dom.rb +102 -0
  331. data/spec/support/servers/arachni/element/ui_form/ui_form_dom.rb +238 -0
  332. data/spec/support/servers/checks/active/trainer_check.rb +7 -7
  333. data/spec/support/servers/checks/active/unvalidated_redirect_dom.rb +22 -6
  334. data/spec/support/servers/checks/active/xss_dom.rb +50 -0
  335. data/spec/support/servers/checks/active/xss_dom_script_context.rb +53 -0
  336. data/spec/support/shared/browser/javascript/taint_tracer/sink/base.rb +6 -6
  337. data/spec/support/shared/check.rb +10 -12
  338. data/spec/support/shared/component/options/base.rb +24 -24
  339. data/spec/support/shared/element/base.rb +25 -25
  340. data/spec/support/shared/element/capabilities/auditable.rb +116 -140
  341. data/spec/support/shared/element/capabilities/dom_only.rb +65 -0
  342. data/spec/support/shared/element/capabilities/inputtable.rb +71 -86
  343. data/spec/support/shared/element/capabilities/mutable.rb +122 -111
  344. data/spec/support/shared/element/capabilities/refreshable.rb +10 -10
  345. data/spec/support/shared/element/capabilities/{submitable.rb → submittable.rb} +26 -26
  346. data/spec/support/shared/element/capabilities/with_auditor.rb +10 -10
  347. data/spec/support/shared/element/capabilities/with_dom.rb +8 -8
  348. data/spec/support/shared/element/capabilities/with_node.rb +4 -6
  349. data/spec/support/shared/element/capabilities/with_scope.rb +2 -2
  350. data/spec/support/shared/element/capabilities/with_source.rb +6 -8
  351. data/spec/support/shared/element/dom.rb +144 -0
  352. data/spec/support/shared/element/dom/auditable.rb +42 -0
  353. data/spec/support/shared/element/dom/inputtable.rb +5 -0
  354. data/spec/support/shared/element/dom/mutable.rb +3 -0
  355. data/spec/support/shared/element/dom/submittable.rb +119 -0
  356. data/spec/support/shared/external/wavsep.rb +3 -3
  357. data/spec/support/shared/fingerprinter.rb +2 -2
  358. data/spec/support/shared/framework.rb +1 -1
  359. data/spec/support/shared/http/message.rb +9 -9
  360. data/spec/support/shared/option_group.rb +17 -17
  361. data/spec/support/shared/path_extractor.rb +1 -1
  362. data/spec/support/shared/plugin.rb +2 -2
  363. data/spec/support/shared/support/cache.rb +57 -57
  364. data/spec/support/shared/support/lookup.rb +25 -25
  365. data/ui/cli/framework.rb +22 -11
  366. data/ui/cli/framework/option_parser.rb +15 -0
  367. data/ui/cli/option_parser.rb +8 -1
  368. data/ui/cli/output.rb +2 -1
  369. metadata +54 -20
  370. data/components/checks/active/xss_dom_inputs.rb +0 -236
  371. data/spec/components/checks/active/xss_dom_inputs_spec.rb +0 -30
  372. data/spec/support/servers/checks/active/xss_dom_inputs.rb +0 -59
  373. data/spec/support/shared/element/capabilities/auditable/dom.rb +0 -322
@@ -16,91 +16,68 @@ describe Arachni::Issue do
16
16
  let( :active_issue ) { Factory[:active_issue] }
17
17
  let( :trusted_issue ) { Factory[:trusted_issue] }
18
18
  let( :untrusted_issue ) { Factory[:untrusted_issue] }
19
- let( :issue_with_variations ) { Factory[:issue_with_variations] }
20
19
 
21
20
  it "supports #{Arachni::RPC::Serializer}" do
22
- duped = Arachni::RPC::Serializer.deep_clone( issue_with_variations )
23
- issue_with_variations.should == duped
24
-
25
- duped.variations.should == issue_with_variations.variations
21
+ duped = Arachni::RPC::Serializer.deep_clone( issue )
22
+ expect(issue).to eq(duped)
26
23
  end
27
24
 
28
25
  it 'recodes string data to UTF8' do
29
- issue.name.should == "Check name \u2713"
26
+ expect(issue.name).to eq("Check name \u2713")
30
27
  end
31
28
 
32
29
  describe '#recheck' do
33
30
  it 'rechecks the issue' do
34
- Arachni::Options.paths.checks = fixtures_path + '/taint_check/'
31
+ Arachni::Options.paths.checks = fixtures_path + '/signature_check/'
35
32
  Arachni::Options.audit.elements :links, :forms, :cookies
36
33
 
37
34
  issue = nil
38
35
  Arachni::Framework.new do |f|
39
36
  f.options.url = "#{web_server_url_for( :auditor )}/link"
40
- f.checks.load :taint
37
+ f.checks.load :signature
41
38
 
42
39
  f.run
43
- issue = f.report.issues.first.variations.first
40
+ issue = f.report.issues.first
44
41
  end
45
42
 
46
- issue.recheck.should == issue
43
+ expect(issue.recheck).to eq(issue)
47
44
  end
48
45
  end
49
46
 
50
47
  describe '#to_rpc_data' do
51
- let(:issue) { issue_with_variations }
52
48
  let(:data) { issue.to_rpc_data }
53
49
 
54
50
  %w(name description platform_name platform_type references cwe
55
51
  remedy_guidance remedy_code tags trusted unique_id digest
56
52
  digest).each do |attribute|
57
53
  it "includes '#{attribute}'" do
58
- data[attribute].should == issue.send( attribute )
54
+ expect(data[attribute]).to eq(issue.send( attribute ))
59
55
  end
60
56
  end
61
57
 
62
- it "includes 'variations'" do
58
+ it "includes 'check'" do
63
59
  check = issue.check.dup
64
- data['check'].should == check.merge(elements: check[:elements].map(&:to_s))
65
- end
66
-
67
- it "includes 'variations'" do
68
- data['variations'].should == issue.variations.map(&:to_rpc_data)
60
+ expect(data['check']).to eq(check.merge(elements: check[:elements].map(&:to_s)))
69
61
  end
70
62
 
71
63
  it "includes 'vector'" do
72
- data['vector'].should == issue.vector.to_rpc_data
64
+ expect(data['vector']).to eq(issue.vector.to_rpc_data)
73
65
  end
74
66
 
75
67
  it "includes 'severity'" do
76
- data['severity'].should == issue.severity.to_s
77
- end
78
-
79
- it "includes 'variation'" do
80
- data['variation'].should == issue.variation?
68
+ expect(data['severity']).to eq(issue.severity.to_s)
81
69
  end
82
70
  end
83
71
 
84
72
  describe '.from_rpc_data' do
85
- let(:issue) { issue_with_variations }
86
73
  let(:restored_issue) { described_class.from_rpc_data data }
87
74
  let(:data) { Arachni::RPC::Serializer.rpc_data( issue ) }
88
75
 
89
76
  %w(name description vector platform_name platform_type references cwe
90
- remedy_guidance remedy_code tags check trusted variations unique_id
77
+ remedy_guidance remedy_code tags check trusted unique_id
91
78
  digest digest severity).each do |attribute|
92
79
  it "restores '#{attribute}'" do
93
- restored_issue.send( attribute ).should == issue.send( attribute )
94
- end
95
- end
96
-
97
- it "restores 'variation'" do
98
- restored_issue.variation?.should == issue.variation?
99
- end
100
-
101
- it 'restores variation parent' do
102
- restored_issue.variations.each do |v|
103
- v.parent.should == restored_issue
80
+ expect(restored_issue.send( attribute )).to eq(issue.send( attribute ))
104
81
  end
105
82
  end
106
83
  end
@@ -109,17 +86,17 @@ describe Arachni::Issue do
109
86
  describe "##{m}" do
110
87
  let(:obj) do
111
88
  obj = Object.new
112
- obj.stub(:deep_clone).and_return(obj)
113
- obj.stub(:prepare_for_report)
89
+ allow(obj).to receive(:deep_clone).and_return(obj)
90
+ allow(obj).to receive(:prepare_for_report)
114
91
  obj
115
92
  end
116
93
 
117
94
  it 'calls #deep_clone' do
118
- obj.should receive(:deep_clone)
95
+ expect(obj).to receive(:deep_clone)
119
96
  empty_issue.send( "#{m}", obj )
120
97
  end
121
98
  it 'calls #prepare_for_report' do
122
- obj.should receive(:prepare_for_report)
99
+ expect(obj).to receive(:prepare_for_report)
123
100
  empty_issue.send( "#{m}", obj )
124
101
  end
125
102
  end
@@ -127,11 +104,11 @@ describe Arachni::Issue do
127
104
 
128
105
  describe '#tags' do
129
106
  it 'returns the set tags' do
130
- issue.tags.should == issue_data[:tags]
107
+ expect(issue.tags).to eq(issue_data[:tags])
131
108
  end
132
109
  context 'when nil' do
133
110
  it 'defaults to an empty array' do
134
- empty_issue.tags.should == []
111
+ expect(empty_issue.tags).to eq([])
135
112
  end
136
113
  end
137
114
  end
@@ -139,17 +116,12 @@ describe Arachni::Issue do
139
116
  describe '#active?' do
140
117
  context 'when the issue was discovered by manipulating an input' do
141
118
  it 'returns true' do
142
- active_issue.active?.should be_true
119
+ expect(active_issue.active?).to be_truthy
143
120
  end
144
121
  end
145
122
  context 'when the issue was logged passively' do
146
123
  it 'returns false' do
147
- passive_issue.active?.should be_false
148
- end
149
- end
150
- context 'when the issue has active variations' do
151
- it 'returns true' do
152
- issue_with_variations.active?.should be_true
124
+ expect(passive_issue.active?).to be_falsey
153
125
  end
154
126
  end
155
127
  end
@@ -157,12 +129,12 @@ describe Arachni::Issue do
157
129
  describe '#passive?' do
158
130
  context 'when the issue was discovered by manipulating an input' do
159
131
  it 'returns false' do
160
- passive_issue.passive?.should be_true
132
+ expect(passive_issue.passive?).to be_truthy
161
133
  end
162
134
  end
163
135
  context 'when the issue was logged passively' do
164
136
  it 'returns true' do
165
- passive_issue.passive?.should be_true
137
+ expect(passive_issue.passive?).to be_truthy
166
138
  end
167
139
  end
168
140
  end
@@ -170,17 +142,17 @@ describe Arachni::Issue do
170
142
  describe '#trusted?' do
171
143
  context 'when the issue is not trusted' do
172
144
  it 'returns false' do
173
- untrusted_issue.trusted?.should be_false
145
+ expect(untrusted_issue.trusted?).to be_falsey
174
146
  end
175
147
  end
176
148
  context 'when the issue does is trusted' do
177
149
  it 'returns true' do
178
- trusted_issue.trusted?.should be_true
150
+ expect(trusted_issue.trusted?).to be_truthy
179
151
  end
180
152
  end
181
153
  context 'by default' do
182
154
  it 'returns true' do
183
- trusted_issue.trusted?.should be_true
155
+ expect(trusted_issue.trusted?).to be_truthy
184
156
  end
185
157
  end
186
158
  end
@@ -188,17 +160,17 @@ describe Arachni::Issue do
188
160
  describe '#untrusted?' do
189
161
  context 'when the issue is not trusted' do
190
162
  it 'returns true' do
191
- untrusted_issue.untrusted?.should be_true
163
+ expect(untrusted_issue.untrusted?).to be_truthy
192
164
  end
193
165
  end
194
166
  context 'when the issue is trusted' do
195
167
  it 'returns false' do
196
- trusted_issue.untrusted?.should be_false
168
+ expect(trusted_issue.untrusted?).to be_falsey
197
169
  end
198
170
  end
199
171
  context 'by default' do
200
172
  it 'returns false' do
201
- issue.untrusted?.should be_false
173
+ expect(issue.untrusted?).to be_falsey
202
174
  end
203
175
  end
204
176
  end
@@ -207,14 +179,15 @@ describe Arachni::Issue do
207
179
  context 'when the issue is' do
208
180
  context 'active' do
209
181
  it 'returns the name of the affected input' do
210
- active_issue.affected_input_name.should ==
182
+ expect(active_issue.affected_input_name).to eq(
211
183
  active_issue.vector.affected_input_name
184
+ )
212
185
  end
213
186
  end
214
187
 
215
188
  context 'passive' do
216
189
  it 'returns nil' do
217
- passive_issue.affected_input_name.should be_nil
190
+ expect(passive_issue.affected_input_name).to be_nil
218
191
  end
219
192
  end
220
193
  end
@@ -224,19 +197,20 @@ describe Arachni::Issue do
224
197
  describe '#cwe=' do
225
198
  it 'assigns a CWE ID and CWE URL based on that ID' do
226
199
  empty_issue.cwe = 20
227
- empty_issue.cwe.should == 20
200
+ expect(empty_issue.cwe).to eq(20)
228
201
  end
229
202
  end
230
203
 
231
204
  describe '#cwe_url' do
232
205
  it 'returns the CWE reference URL' do
233
- described_class.new( vector: vector, cwe: 21 ).cwe_url.should ==
206
+ expect(described_class.new( vector: vector, cwe: 21 ).cwe_url).to eq(
234
207
  'http://cwe.mitre.org/data/definitions/21.html'
208
+ )
235
209
  end
236
210
 
237
211
  context 'when no #cwe has been given' do
238
212
  it 'returns nil' do
239
- described_class.new( vector: vector, cwe: nil ).cwe_url.should be_nil
213
+ expect(described_class.new( vector: vector, cwe: nil ).cwe_url).to be_nil
240
214
  end
241
215
  end
242
216
  end
@@ -247,7 +221,7 @@ describe Arachni::Issue do
247
221
  signature = /test.*/
248
222
 
249
223
  empty_issue.signature = signature
250
- empty_issue.signature.should == signature.source
224
+ expect(empty_issue.signature).to eq(signature.source)
251
225
  end
252
226
  end
253
227
 
@@ -256,14 +230,14 @@ describe Arachni::Issue do
256
230
  signature = 'stuff'
257
231
 
258
232
  empty_issue.signature = signature
259
- empty_issue.signature.should == signature
233
+ expect(empty_issue.signature).to eq(signature)
260
234
  end
261
235
  end
262
236
 
263
237
  context 'when no signature has been given' do
264
238
  it 'returns nil' do
265
239
  empty_issue.signature = nil
266
- empty_issue.signature.should be_nil
240
+ expect(empty_issue.signature).to be_nil
267
241
  end
268
242
  end
269
243
  end
@@ -272,24 +246,24 @@ describe Arachni::Issue do
272
246
  it 'assigns a references hash' do
273
247
  refs = { 'title' => 'url' }
274
248
  empty_issue.references = refs
275
- empty_issue.references.should == refs
249
+ expect(empty_issue.references).to eq(refs)
276
250
  end
277
251
  context 'when nil is passed as a value' do
278
252
  it 'falls-back to an empty Hash' do
279
- empty_issue.references.should == {}
253
+ expect(empty_issue.references).to eq({})
280
254
  empty_issue.references = nil
281
- empty_issue.references.should == {}
255
+ expect(empty_issue.references).to eq({})
282
256
  end
283
257
  end
284
258
  end
285
259
 
286
260
  describe '#remarks' do
287
261
  it 'returns the set remarks as a Hash' do
288
- issue.remarks.should == issue_data[:remarks]
262
+ expect(issue.remarks).to eq(issue_data[:remarks])
289
263
  end
290
264
  context 'when uninitialised' do
291
265
  it 'falls-back to an empty Hash' do
292
- empty_issue.remarks.should == {}
266
+ expect(empty_issue.remarks).to eq({})
293
267
  end
294
268
  end
295
269
  end
@@ -301,7 +275,7 @@ describe Arachni::Issue do
301
275
 
302
276
  empty_issue.add_remark author, remarks.first
303
277
  empty_issue.add_remark author, remarks[1]
304
- empty_issue.remarks.should == { author => remarks }
278
+ expect(empty_issue.remarks).to eq({ author => remarks })
305
279
  end
306
280
 
307
281
  context 'when an argument is blank' do
@@ -312,7 +286,7 @@ describe Arachni::Issue do
312
286
  rescue ArgumentError
313
287
  raised = true
314
288
  end
315
- raised.should be_true
289
+ expect(raised).to be_truthy
316
290
 
317
291
  raised = false
318
292
  begin
@@ -320,7 +294,7 @@ describe Arachni::Issue do
320
294
  rescue ArgumentError
321
295
  raised = true
322
296
  end
323
- raised.should be_true
297
+ expect(raised).to be_truthy
324
298
 
325
299
  raised = false
326
300
  begin
@@ -328,7 +302,7 @@ describe Arachni::Issue do
328
302
  rescue ArgumentError
329
303
  raised = true
330
304
  end
331
- raised.should be_true
305
+ expect(raised).to be_truthy
332
306
 
333
307
  raised = false
334
308
  begin
@@ -336,7 +310,7 @@ describe Arachni::Issue do
336
310
  rescue ArgumentError
337
311
  raised = true
338
312
  end
339
- raised.should be_true
313
+ expect(raised).to be_truthy
340
314
  end
341
315
  end
342
316
  end
@@ -386,10 +360,12 @@ describe Arachni::Issue do
386
360
  issue_h[:referring_page][:dom][:execution_flow_sinks] =
387
361
  issue_h[:referring_page][:dom][:execution_flow_sinks].map(&:to_h)
388
362
 
389
- issue_h.should == {
363
+ expect(issue_h).to eq({
390
364
  name: "Check name \u2713",
391
365
  description: 'Issue description',
392
- vector: issue.vector.to_h,
366
+ vector: issue.vector.to_h.merge(
367
+ affected_input_name: issue.affected_input_name
368
+ ),
393
369
  referring_page: {
394
370
  body: issue.referring_page.body,
395
371
  dom: referring_page_dom_h
@@ -421,160 +397,45 @@ describe Arachni::Issue do
421
397
  shortname: 'test'
422
398
  },
423
399
  trusted: true,
424
- digest: 3311937213,
400
+ digest: issue.digest,
425
401
  request: issue.request.to_h,
426
402
  cwe: 1,
427
- variations: [],
428
403
  cwe_url: 'http://cwe.mitre.org/data/definitions/1.html'
429
- }
430
- end
431
-
432
- context 'when the issue has variations' do
433
- it 'includes those variations' do
434
- page = Factory[:page].dup
435
- page.body = "#{page.body}stuff"
436
-
437
- issue_with_variations.variations.each { |v| v.referring_page = page }
438
-
439
- issue_h = issue_with_variations.to_h
440
- variations = issue_h.delete( :variations )
441
-
442
- issue_h.should == {
443
- name: "Check name \u2713",
444
- description: 'Issue description',
445
- platform_name: :unix,
446
- platform_type: :os,
447
- references: { 'Title' => 'http://some/url' },
448
- severity: :high,
449
- remedy_guidance: 'How to fix the issue.',
450
- remedy_code: 'Sample code on how to fix the issue',
451
- tags: %w(these are a few tags),
452
- check: {
453
- name: 'Test check',
454
- description: 'Test description',
455
- author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com> ',
456
- version: '0.1',
457
- targets: {
458
- 'Generic' => 'all'
459
- },
460
- elements: [:link, :form_dom],
461
- shortname: 'test'
462
- },
463
- digest: 58999149,
464
- cwe: 1,
465
- variation: false,
466
- trusted: true,
467
- vector: {
468
- method: :get,
469
- type: :form,
470
- class: 'Arachni::Element::Form',
471
- url: 'http://test.com/',
472
- action: 'http://test.com/',
473
- inputs: { 'stuff' => '1' },
474
- affected_input_name: 'stuff',
475
- source: nil
476
- },
477
- cwe_url: 'http://cwe.mitre.org/data/definitions/1.html'
478
- }
479
-
480
- variations.each_with_index do |variation, i|
481
- dom_h = issue.page.dom.to_h
482
- dom_h.delete(:skip_states)
483
- dom_h[:transitions] = dom_h[:transitions].map do |t|
484
- h = t.to_hash
485
- h.delete(:time)
486
- h
487
- end
488
-
489
- referring_page_dom_h = variation[:referring_page][:dom]
490
- referring_page_dom_h.delete(:skip_states)
491
- referring_page_dom_h[:transitions] =
492
- referring_page_dom_h[:transitions].map do |t|
493
- h = t.to_hash
494
- h.delete(:time)
495
- h
496
- end
497
-
498
-
499
- variation[:page][:dom][:transitions] =
500
- variation[:page][:dom][:transitions].map do |h|
501
- h.delete(:time)
502
- h
503
- end
504
- variation[:page][:dom][:data_flow_sinks] =
505
- variation[:page][:dom][:data_flow_sinks].map(&:to_h)
506
- variation[:page][:dom][:execution_flow_sinks] =
507
- variation[:page][:dom][:execution_flow_sinks].map(&:to_h)
508
-
509
- variation[:referring_page][:dom][:transitions] =
510
- variation[:page][:dom][:transitions].map do |h|
511
- h.delete(:time)
512
- h
513
- end
514
- variation[:referring_page][:dom][:data_flow_sinks] =
515
- variation[:referring_page][:dom][:data_flow_sinks].map(&:to_h)
516
- variation[:referring_page][:dom][:execution_flow_sinks] =
517
- variation[:referring_page][:dom][:execution_flow_sinks].map(&:to_h)
518
-
519
- variation.should == {
520
- vector: {
521
- method: :get,
522
- inputs: { 'stuff' => i.to_s },
523
- affected_input_value: i.to_s,
524
- seed: i.to_s,
525
- class: Arachni::Element::Form.to_s,
526
- },
527
- referring_page: {
528
- body: page.body,
529
- dom: referring_page_dom_h
530
- },
531
- page: {
532
- body: issue.page.body,
533
- dom: dom_h
534
- },
535
- response: issue.response.to_h,
536
- remarks: { the_dude: %w(Hey!) },
537
- signature: 'some regexp',
538
- proof: "string matched by '/some regexp/'",
539
- trusted: true,
540
- request: issue.request.to_h,
541
- variation: true
542
- }
543
- end
544
- end
404
+ })
545
405
  end
546
406
  end
547
407
 
548
408
  describe '#unique_id' do
549
409
  it 'returns a string uniquely identifying the issue' do
550
410
  i = active_issue
551
- i.unique_id.should ==
411
+ expect(i.unique_id).to eq(
552
412
  "#{i.name}:#{i.vector.method}:#{i.vector.affected_input_name}:#{i.vector.url}"
413
+ )
553
414
 
554
415
  i = passive_issue
555
- i.unique_id.should == "#{i.name}:#{i.vector.url}"
416
+ expect(i.unique_id).to eq("#{i.name}:#{i.proof}:#{i.vector.url}")
556
417
  end
557
418
  end
558
419
 
559
420
  describe '#eql?' do
560
421
  context 'when 2 issues are equal' do
561
422
  it 'returns true' do
562
- issue.eql?( issue ).should be_true
423
+ expect(issue.eql?( issue )).to be_truthy
563
424
  end
564
425
  end
565
426
  context 'when 2 issues are not equal' do
566
427
  it 'returns false' do
567
428
  i = issue.deep_clone
568
429
  i.name = 'stuff'
569
- issue.eql?( i ).should be_false
430
+ expect(issue.eql?( i )).to be_falsey
570
431
 
571
432
  i = issue.deep_clone
572
433
  i.vector.action = 'http://stuff'
573
- issue.eql?( i ).should be_false
434
+ expect(issue.eql?( i )).to be_falsey
574
435
 
575
436
  i = issue.deep_clone
576
437
  i.vector.affected_input_name = 'Stuff'
577
- issue.eql?( i ).should be_false
438
+ expect(issue.eql?( i )).to be_falsey
578
439
  end
579
440
 
580
441
  context 'when the issue is' do
@@ -582,206 +443,47 @@ describe Arachni::Issue do
582
443
  it 'takes into account the vector method' do
583
444
  i = active_issue.deep_clone
584
445
  i.vector.method = :post
585
- active_issue.eql?( i ).should be_false
446
+ expect(active_issue.eql?( i )).to be_falsey
586
447
  end
587
448
  end
588
449
  context 'passive' do
589
450
  it 'does not take into account the vector method' do
590
451
  i = issue.deep_clone
591
452
  i.vector.method = :post
592
- issue.eql?( i ).should be_true
453
+ expect(issue.eql?( i )).to be_truthy
593
454
  end
594
455
  end
595
456
  end
596
457
  end
597
458
  end
598
459
 
599
- describe '#with_variations' do
600
- it 'returns a copy of the issue with variation data removed' do
601
- variation_data = [ :response, :proof, :signature, :remarks ]
602
-
603
- variation_data.each do |k|
604
- issue.send(k).should be_true
605
- end
606
-
607
- root = issue.with_variations
608
- variation_data.each do |k|
609
- root.send(k).should be_nil
610
- end
611
- root.variations.should == []
612
- end
613
-
614
- it 'removes specific issue data from the vector' do
615
- vector = active_issue.vector
616
- vector.affected_input_name.should be_true
617
- vector.affected_input_value.should be_true
618
- vector.seed.should be_true
619
-
620
- vector = active_issue.with_variations.vector
621
- vector.affected_input_name.should be_nil
622
- vector.affected_input_value.should be_nil
623
- vector.seed.should be_nil
624
- end
625
- end
626
-
627
- describe '#as_variation' do
628
- it 'returns a copy of the issue with generic data removed' do
629
- variation_data = [
630
- :name, :description, :platform_name, :platform_type, :references,
631
- :cwe, :severity, :remedy_guidance, :remedy_code, :tags, :check,
632
- :cwe_url
633
- ]
634
-
635
- variation_data.each do |k|
636
- issue.send(k).should be_true
637
- end
638
-
639
- root = issue.as_variation
640
- variation_data.each do |k|
641
- root.send(k).should be_nil
642
- end
643
- root.variations.should be_nil
644
- end
645
-
646
- it 'has a #parent' do
647
- issue.as_variation.parent.should == issue
648
- end
649
- end
650
-
651
- describe '#to_solo!' do
652
- it 'converts a variation to a solo issue in place, using a parent as a reference' do
653
- original_solo = issue
654
- parent = issue.with_variations
655
- variation = issue.as_variation
656
-
657
- original_solo.should be_solo
658
- parent.should_not be_variation
659
- variation.should be_variation
660
-
661
- solo = variation.to_solo!( parent )
662
- solo.should be_solo
663
-
664
- solo.to_h.should == original_solo.to_h
665
- solo.to_h.should == variation.to_h
666
- solo.object_id.should == variation.object_id
667
- end
668
-
669
- it 'skips #variations' do
670
- parent = issue.with_variations
671
- variation = issue.as_variation
672
-
673
- parent.variations << variation
674
-
675
- parent.variations.should be_any
676
- variation.to_solo!( parent ).variations.should be_empty
677
- end
678
-
679
- it 'skips #vector' do
680
- parent = active_issue.with_variations
681
- variation = active_issue.as_variation
682
-
683
- parent.vector.affected_input_name.should be_nil
684
- variation.vector.affected_input_name.should be_true
685
- variation.to_solo!( parent ).vector.affected_input_name.should be_true
686
- end
687
-
688
- it 'skips #parent' do
689
- parent = issue.with_variations
690
- variation = issue.as_variation
691
-
692
- variation.to_solo!( parent ).parent.should be_nil
693
- end
694
- end
695
-
696
- describe '#to_solo' do
697
- it 'returns a solo issue using a parent as a reference' do
698
- original_solo = issue
699
- parent = issue.with_variations
700
- variation = issue.as_variation
701
-
702
- original_solo.should be_solo
703
- parent.should_not be_variation
704
- variation.should be_variation
705
-
706
- solo = variation.to_solo( parent )
707
- solo.should be_solo
708
-
709
- solo.to_h.should == original_solo.to_h
710
- solo.object_id.should_not == variation.object_id
711
- end
712
- end
713
-
714
- describe '#variation?' do
715
- context 'when the issue is' do
716
- context 'variation' do
717
- it 'returns true' do
718
- issue.as_variation.should be_variation
719
- end
720
- end
721
-
722
- context 'parent' do
723
- it 'returns false' do
724
- issue.with_variations.should_not be_variation
725
- end
726
- end
727
-
728
- context 'solo' do
729
- it 'returns false' do
730
- issue.should_not be_variation
731
- end
732
- end
733
- end
734
- end
735
-
736
- describe '#solo?' do
737
- context 'when the issue is' do
738
- context 'variation' do
739
- it 'returns false' do
740
- issue.as_variation.should_not be_solo
741
- end
742
- end
743
-
744
- context 'parent' do
745
- it 'returns false' do
746
- issue.with_variations.should_not be_solo
747
- end
748
- end
749
-
750
- context 'solo' do
751
- it 'returns true' do
752
- issue.should be_solo
753
- end
754
- end
755
- end
756
- end
757
-
758
460
  describe '#hash' do
759
461
  context 'when 2 issues are equal' do
760
462
  it 'have the same hash' do
761
- issue.hash.should == issue.hash
463
+ expect(issue.hash).to eq(issue.hash)
762
464
  end
763
465
  end
764
466
  context 'when 2 issues are not equal' do
765
467
  it 'returns false' do
766
468
  i = issue.deep_clone
767
469
  i.name = 'stuff'
768
- issue.hash.should_not == i.hash
470
+ expect(issue.hash).not_to eq(i.hash)
769
471
 
770
472
  i = issue.deep_clone
771
473
  i.vector.action = 'http://stuff'
772
- issue.hash.should_not == i.hash
474
+ expect(issue.hash).not_to eq(i.hash)
773
475
 
774
476
  i = issue.deep_clone
775
477
  i.vector.affected_input_name = 'Stuff'
776
- issue.hash.should_not == i.hash
478
+ expect(issue.hash).not_to eq(i.hash)
777
479
  end
778
480
  end
779
481
  end
780
482
 
781
483
  describe '#digest' do
782
484
  it 'returns a Integer hash based on #unique_id' do
783
- issue.digest.should be_kind_of Integer
784
- issue.digest.should == issue.unique_id.persistent_hash
485
+ expect(issue.digest).to be_kind_of Integer
486
+ expect(issue.digest).to eq(issue.unique_id.persistent_hash)
785
487
  end
786
488
  end
787
489