muck-users 0.2.23 → 0.3.0

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 (67) hide show
  1. data/README.rdoc +3 -1
  2. data/VERSION +1 -1
  3. data/app/controllers/admin/muck/access_codes_controller.rb +78 -0
  4. data/app/controllers/admin/muck/roles_controller.rb +34 -24
  5. data/app/controllers/admin/muck/users_controller.rb +56 -21
  6. data/app/controllers/muck/access_code_requests_controller.rb +27 -0
  7. data/app/controllers/muck/activations_controller.rb +0 -1
  8. data/app/controllers/muck/users_controller.rb +122 -110
  9. data/app/models/role.rb +5 -2
  10. data/app/models/user_mailer.rb +7 -0
  11. data/app/views/access_code_requests/new.html.erb +7 -0
  12. data/app/views/access_code_requests/show.html.erb +1 -0
  13. data/app/views/admin/access_codes/_access_code.html.erb +8 -0
  14. data/app/views/admin/access_codes/_form.html.erb +15 -0
  15. data/app/views/admin/access_codes/_user.html.erb +6 -0
  16. data/app/views/admin/access_codes/bulk.html.erb +12 -0
  17. data/app/views/admin/access_codes/edit.html.erb +6 -0
  18. data/app/views/admin/access_codes/index.html.erb +18 -0
  19. data/app/views/admin/access_codes/new.html.erb +6 -0
  20. data/app/views/admin/access_codes/show.html.erb +30 -0
  21. data/app/views/admin/permissions/_permission.html.erb +3 -0
  22. data/app/views/admin/roles/_role.html.erb +5 -9
  23. data/app/views/admin/roles/edit.html.erb +4 -17
  24. data/app/views/admin/roles/index.html.erb +16 -8
  25. data/app/views/admin/roles/new.html.erb +4 -16
  26. data/app/views/admin/roles/show.html.erb +3 -7
  27. data/app/views/admin/users/_activate.html.erb +2 -2
  28. data/app/views/admin/users/_row.html.erb +8 -2
  29. data/app/views/admin/users/_table.html.erb +10 -15
  30. data/app/views/admin/users/permissions.html.erb +8 -0
  31. data/app/views/user_mailer/access_code.text.html.erb +3 -0
  32. data/app/views/user_mailer/access_code.text.plain.erb +5 -0
  33. data/app/views/users/_signup_form.html.erb +7 -0
  34. data/app/views/users/welcome.html.erb +1 -1
  35. data/config/muck_users_routes.rb +5 -2
  36. data/db/migrate/20100123035450_create_access_codes.rb +19 -0
  37. data/db/migrate/20100123233654_create_access_code_requests.rb +14 -0
  38. data/lib/action_controller/authentic_application.rb +1 -1
  39. data/lib/active_record/acts/muck_access_code.rb +75 -0
  40. data/lib/active_record/acts/muck_access_code_request.rb +33 -0
  41. data/lib/active_record/acts/muck_user.rb +13 -1
  42. data/lib/muck_users.rb +8 -1
  43. data/lib/muck_users/muck_custom_form_builder.rb +10 -0
  44. data/locales/en.yml +163 -102
  45. data/muck-users.gemspec +41 -2
  46. data/test/rails_root/app/models/access_code.rb +3 -0
  47. data/test/rails_root/app/models/access_code_request.rb +3 -0
  48. data/test/rails_root/app/models/user.rb +12 -9
  49. data/test/rails_root/config/environment.rb +1 -0
  50. data/test/rails_root/config/global_config.yml +1 -1
  51. data/test/rails_root/db/migrate/20100123035450_create_access_codes.rb +19 -0
  52. data/test/rails_root/db/migrate/20100123233654_create_access_code_requests.rb +14 -0
  53. data/test/rails_root/public/javascripts/jquery/jquery.jgrowl.js +9 -2
  54. data/test/rails_root/public/javascripts/muck.js +39 -13
  55. data/test/rails_root/public/stylesheets/admin.css +20 -3
  56. data/test/rails_root/public/stylesheets/jquery/cupertino/jquery-ui-1.7.2.custom.css +160 -0
  57. data/test/rails_root/public/stylesheets/jquery/redmond/jquery-ui-1.7.2.custom.css +160 -0
  58. data/test/rails_root/public/stylesheets/jquery/smoothness/jquery-ui-1.7.2.custom.css +160 -0
  59. data/test/rails_root/public/stylesheets/jquery/ui-lightness/jquery-ui-1.7.2.custom.css +160 -0
  60. data/test/rails_root/public/stylesheets/styles.css +9 -8
  61. data/test/rails_root/test/functional/access_code_requests_controller_test.rb +33 -0
  62. data/test/rails_root/test/functional/admin/access_codes_controller_test.rb +166 -0
  63. data/test/rails_root/test/unit/access_code_test.rb +100 -0
  64. data/test/rails_root/test/unit/role_test.rb +1 -0
  65. data/test/rails_root/test/unit/user_mailer_test.rb +13 -1
  66. data/test/rails_root/test/unit/user_test.rb +13 -9
  67. metadata +41 -2
@@ -0,0 +1,160 @@
1
+ /*
2
+ * jQuery UI CSS Framework
3
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
4
+ * Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
5
+ */
6
+
7
+ /* Layout helpers
8
+ ----------------------------------*/
9
+ .ui-helper-hidden { display: none; }
10
+ .ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
11
+ .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
12
+ .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
13
+ .ui-helper-clearfix { display: inline-block; }
14
+ /* required comment for clearfix to work in Opera \*/
15
+ * html .ui-helper-clearfix { height:1%; }
16
+ .ui-helper-clearfix { display:block; }
17
+ /* end clearfix */
18
+ .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
19
+
20
+
21
+ /* Interaction Cues
22
+ ----------------------------------*/
23
+ .ui-state-disabled { cursor: default !important; }
24
+
25
+
26
+ /* Icons
27
+ ----------------------------------*/
28
+
29
+ /* states and images */
30
+ .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
31
+
32
+
33
+ /* Misc visuals
34
+ ----------------------------------*/
35
+
36
+ /* Overlays */
37
+ .ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }/* Accordion
38
+ ----------------------------------*/
39
+ .ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
40
+ .ui-accordion .ui-accordion-li-fix { display: inline; }
41
+ .ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
42
+ .ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; }
43
+ .ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
44
+ .ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
45
+ .ui-accordion .ui-accordion-content-active { display: block; }/* Datepicker
46
+ ----------------------------------*/
47
+ .ui-datepicker { width: 17em; padding: .2em .2em 0; }
48
+ .ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
49
+ .ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
50
+ .ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
51
+ .ui-datepicker .ui-datepicker-prev { left:2px; }
52
+ .ui-datepicker .ui-datepicker-next { right:2px; }
53
+ .ui-datepicker .ui-datepicker-prev-hover { left:1px; }
54
+ .ui-datepicker .ui-datepicker-next-hover { right:1px; }
55
+ .ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
56
+ .ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
57
+ .ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; }
58
+ .ui-datepicker select.ui-datepicker-month-year {width: 100%;}
59
+ .ui-datepicker select.ui-datepicker-month,
60
+ .ui-datepicker select.ui-datepicker-year { width: 49%;}
61
+ .ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; }
62
+ .ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
63
+ .ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
64
+ .ui-datepicker td { border: 0; padding: 1px; }
65
+ .ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
66
+ .ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
67
+ .ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
68
+ .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
69
+
70
+ /* with multiple calendars */
71
+ .ui-datepicker.ui-datepicker-multi { width:auto; }
72
+ .ui-datepicker-multi .ui-datepicker-group { float:left; }
73
+ .ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
74
+ .ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
75
+ .ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
76
+ .ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
77
+ .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
78
+ .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
79
+ .ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
80
+ .ui-datepicker-row-break { clear:both; width:100%; }
81
+
82
+ /* RTL support */
83
+ .ui-datepicker-rtl { direction: rtl; }
84
+ .ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
85
+ .ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
86
+ .ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
87
+ .ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
88
+ .ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
89
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
90
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
91
+ .ui-datepicker-rtl .ui-datepicker-group { float:right; }
92
+ .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
93
+ .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
94
+
95
+ /* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
96
+ .ui-datepicker-cover {
97
+ display: none; /*sorry for IE5*/
98
+ display/**/: block; /*sorry for IE5*/
99
+ position: absolute; /*must have*/
100
+ z-index: -1; /*must have*/
101
+ filter: mask(); /*must have*/
102
+ top: -4px; /*must have*/
103
+ left: -4px; /*must have*/
104
+ width: 200px; /*must have*/
105
+ height: 200px; /*must have*/
106
+ }/* Dialog
107
+ ----------------------------------*/
108
+ .ui-dialog { position: relative; padding: .2em; width: 300px; }
109
+ .ui-dialog .ui-dialog-titlebar { padding: .5em .3em .3em 1em; position: relative; }
110
+ .ui-dialog .ui-dialog-title { float: left; margin: .1em 0 .2em; }
111
+ .ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
112
+ .ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
113
+ .ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
114
+ .ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
115
+ .ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
116
+ .ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
117
+ .ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
118
+ .ui-draggable .ui-dialog-titlebar { cursor: move; }
119
+ /* Progressbar
120
+ ----------------------------------*/
121
+ .ui-progressbar { height:2em; text-align: left; }
122
+ .ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }/* Resizable
123
+ ----------------------------------*/
124
+ .ui-resizable { position: relative;}
125
+ .ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
126
+ .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
127
+ .ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
128
+ .ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
129
+ .ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
130
+ .ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
131
+ .ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
132
+ .ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
133
+ .ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
134
+ .ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Slider
135
+ ----------------------------------*/
136
+ .ui-slider { position: relative; text-align: left; }
137
+ .ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
138
+ .ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; }
139
+
140
+ .ui-slider-horizontal { height: .8em; }
141
+ .ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
142
+ .ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
143
+ .ui-slider-horizontal .ui-slider-range-min { left: 0; }
144
+ .ui-slider-horizontal .ui-slider-range-max { right: 0; }
145
+
146
+ .ui-slider-vertical { width: .8em; height: 100px; }
147
+ .ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
148
+ .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
149
+ .ui-slider-vertical .ui-slider-range-min { bottom: 0; }
150
+ .ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs
151
+ ----------------------------------*/
152
+ .ui-tabs { padding: .2em; zoom: 1; }
153
+ .ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; }
154
+ .ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; }
155
+ .ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; }
156
+ .ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; }
157
+ .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
158
+ .ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
159
+ .ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; }
160
+ .ui-tabs .ui-tabs-hide { display: none !important; }
@@ -0,0 +1,160 @@
1
+ /*
2
+ * jQuery UI CSS Framework
3
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
4
+ * Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
5
+ */
6
+
7
+ /* Layout helpers
8
+ ----------------------------------*/
9
+ .ui-helper-hidden { display: none; }
10
+ .ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
11
+ .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
12
+ .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
13
+ .ui-helper-clearfix { display: inline-block; }
14
+ /* required comment for clearfix to work in Opera \*/
15
+ * html .ui-helper-clearfix { height:1%; }
16
+ .ui-helper-clearfix { display:block; }
17
+ /* end clearfix */
18
+ .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
19
+
20
+
21
+ /* Interaction Cues
22
+ ----------------------------------*/
23
+ .ui-state-disabled { cursor: default !important; }
24
+
25
+
26
+ /* Icons
27
+ ----------------------------------*/
28
+
29
+ /* states and images */
30
+ .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
31
+
32
+
33
+ /* Misc visuals
34
+ ----------------------------------*/
35
+
36
+ /* Overlays */
37
+ .ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }/* Accordion
38
+ ----------------------------------*/
39
+ .ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
40
+ .ui-accordion .ui-accordion-li-fix { display: inline; }
41
+ .ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
42
+ .ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; }
43
+ .ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
44
+ .ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
45
+ .ui-accordion .ui-accordion-content-active { display: block; }/* Datepicker
46
+ ----------------------------------*/
47
+ .ui-datepicker { width: 17em; padding: .2em .2em 0; }
48
+ .ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
49
+ .ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
50
+ .ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
51
+ .ui-datepicker .ui-datepicker-prev { left:2px; }
52
+ .ui-datepicker .ui-datepicker-next { right:2px; }
53
+ .ui-datepicker .ui-datepicker-prev-hover { left:1px; }
54
+ .ui-datepicker .ui-datepicker-next-hover { right:1px; }
55
+ .ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
56
+ .ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
57
+ .ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; }
58
+ .ui-datepicker select.ui-datepicker-month-year {width: 100%;}
59
+ .ui-datepicker select.ui-datepicker-month,
60
+ .ui-datepicker select.ui-datepicker-year { width: 49%;}
61
+ .ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; }
62
+ .ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
63
+ .ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
64
+ .ui-datepicker td { border: 0; padding: 1px; }
65
+ .ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
66
+ .ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
67
+ .ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
68
+ .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
69
+
70
+ /* with multiple calendars */
71
+ .ui-datepicker.ui-datepicker-multi { width:auto; }
72
+ .ui-datepicker-multi .ui-datepicker-group { float:left; }
73
+ .ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
74
+ .ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
75
+ .ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
76
+ .ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
77
+ .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
78
+ .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
79
+ .ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
80
+ .ui-datepicker-row-break { clear:both; width:100%; }
81
+
82
+ /* RTL support */
83
+ .ui-datepicker-rtl { direction: rtl; }
84
+ .ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
85
+ .ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
86
+ .ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
87
+ .ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
88
+ .ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
89
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
90
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
91
+ .ui-datepicker-rtl .ui-datepicker-group { float:right; }
92
+ .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
93
+ .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
94
+
95
+ /* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
96
+ .ui-datepicker-cover {
97
+ display: none; /*sorry for IE5*/
98
+ display/**/: block; /*sorry for IE5*/
99
+ position: absolute; /*must have*/
100
+ z-index: -1; /*must have*/
101
+ filter: mask(); /*must have*/
102
+ top: -4px; /*must have*/
103
+ left: -4px; /*must have*/
104
+ width: 200px; /*must have*/
105
+ height: 200px; /*must have*/
106
+ }/* Dialog
107
+ ----------------------------------*/
108
+ .ui-dialog { position: relative; padding: .2em; width: 300px; }
109
+ .ui-dialog .ui-dialog-titlebar { padding: .5em .3em .3em 1em; position: relative; }
110
+ .ui-dialog .ui-dialog-title { float: left; margin: .1em 0 .2em; }
111
+ .ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
112
+ .ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
113
+ .ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
114
+ .ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
115
+ .ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
116
+ .ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
117
+ .ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
118
+ .ui-draggable .ui-dialog-titlebar { cursor: move; }
119
+ /* Progressbar
120
+ ----------------------------------*/
121
+ .ui-progressbar { height:2em; text-align: left; }
122
+ .ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }/* Resizable
123
+ ----------------------------------*/
124
+ .ui-resizable { position: relative;}
125
+ .ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
126
+ .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
127
+ .ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
128
+ .ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
129
+ .ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
130
+ .ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
131
+ .ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
132
+ .ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
133
+ .ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
134
+ .ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Slider
135
+ ----------------------------------*/
136
+ .ui-slider { position: relative; text-align: left; }
137
+ .ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
138
+ .ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; }
139
+
140
+ .ui-slider-horizontal { height: .8em; }
141
+ .ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
142
+ .ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
143
+ .ui-slider-horizontal .ui-slider-range-min { left: 0; }
144
+ .ui-slider-horizontal .ui-slider-range-max { right: 0; }
145
+
146
+ .ui-slider-vertical { width: .8em; height: 100px; }
147
+ .ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
148
+ .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
149
+ .ui-slider-vertical .ui-slider-range-min { bottom: 0; }
150
+ .ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs
151
+ ----------------------------------*/
152
+ .ui-tabs { padding: .2em; zoom: 1; }
153
+ .ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; }
154
+ .ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; }
155
+ .ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; }
156
+ .ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; }
157
+ .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
158
+ .ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
159
+ .ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; }
160
+ .ui-tabs .ui-tabs-hide { display: none !important; }
@@ -55,7 +55,7 @@ ul.icon-list a{display:inline-block;margin:2px 0;padding:2px 0 5px 28px;text-dec
55
55
  .bottom-tip #tip-header, .right-tip #tip-header{background-position:left top;}
56
56
 
57
57
  /*jGrowl*/
58
- div.jGrowl{padding:10px;z-index:9999;}
58
+ div.jGrowl{padding:10px;z-index:9999;color:#fff;font-size:12px;}
59
59
  /** Special IE6 Style Positioning **/
60
60
  div.ie6{position:absolute;}
61
61
  div.ie6.top-right{right:auto;bottom:auto;left:expression( ( 0 - jGrowl.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth :document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft :document.body.scrollLeft ) ) + 'px' );top:expression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop :document.body.scrollTop ) ) + 'px' );}
@@ -72,14 +72,15 @@ body > div.jGrowl.bottom-right{right:0px;bottom:0px;}
72
72
  body > div.jGrowl.center{top:0px;width:50%;left:25%;}
73
73
  /** Cross Browser Styling **/
74
74
  div.center div.jGrowl-notification,div.center div.jGrowl-closer{margin-left:auto;margin-right:auto;}
75
- div.jGrowl div.jGrowl-notification,div.jGrowl div.jGrowl-closer{background-color:#F0F7F9;color:#000;opacity:.95;filter:alpha(opacity = 95);zoom:1;width:550px;padding:10px;margin-top:5px;margin-bottom:5px;font-size:1.5em;text-align:left;display:none;-moz-border-radius:5px;-webkit-border-radius:5px;border:solid 3px #555;}
75
+ div.jGrowl div.jGrowl-notification,div.jGrowl div.jGrowl-closer{background-color:#000;opacity:.85;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=85)";filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=85);zoom:1;width:235px;padding:10px;margin-top:5px;margin-bottom:5px;font-family:Tahoma,Arial,Helvetica,sans-serif;font-size:1em;text-align:left;display:none;-moz-border-radius:5px;-webkit-border-radius:5px;}
76
76
  div.jGrowl div.jGrowl-notification{min-height:40px;}
77
- div.jGrowl div.jGrowl-notification div.header{font-weight:bold;font-size:1.6em;}
78
- div.jGrowl div.jGrowl-notification div.close{float:right;font-weight:bold;font-size:2em;cursor:pointer;color:#555;}
79
- div.jGrowl div.jGrowl-notification div.close:hover{color:#ccc;}
80
- div.jGrowl div.jGrowl-closer{height:15px;padding-top:4px;padding-bottom:4px;cursor:pointer;font-size:11px;font-weight:bold;text-align:center;}
81
- div.jGrowl div.jGrowl-notification .notice, div.jGrowl div.jGrowl-notification .error, div.jGrowl div.jGrowl-notification .success{background:none;border:none;}
82
- div.jGrowl div.jGrowl-notification h2{text-align:left;font-weight:bold;padding:5px 5px 5px 15px;font-size:1.1em;}
77
+ div.jGrowl div.jGrowl-notification div.header{font-weight:bold;font-size:.85em;}
78
+ div.jGrowl div.jGrowl-notification div.close{z-index:99;float:right;font-weight:bold;font-size:1em;cursor:pointer;}
79
+ div.jGrowl div.jGrowl-closer{padding-top:4px;padding-bottom:4px;cursor:pointer;font-size:.9em;font-weight:bold;text-align:center;}
80
+ /** Hide jGrowl when printing **/
81
+ @media print{div.jGrowl{display:none;}
82
+ }
83
+
83
84
 
84
85
  /* Errors */
85
86
  .help-box{font-size:1.2em;color:#555;}
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class Muck::AccessCodeRequestsControllerTest < ActionController::TestCase
4
+
5
+ tests Muck::AccessCodeRequestsController
6
+
7
+ context "access code requests controller" do
8
+
9
+ context "GET show" do
10
+ setup do
11
+ get :show
12
+ end
13
+ should_respond_with :success
14
+ should_render_template :show
15
+ end
16
+
17
+ context "GET new" do
18
+ setup do
19
+ get :new
20
+ end
21
+ should_respond_with :success
22
+ should_render_template :new
23
+ end
24
+
25
+ context "POST to create" do
26
+ setup do
27
+ post :create, :access_code_request => { :email => Factory.next(:email) }
28
+ end
29
+ should_redirect_to("show access request") { access_code_request_path(assigns(:access_code_request)) }
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,166 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper'
2
+
3
+ class Admin::Muck::AccessCodesControllerTest < ActionController::TestCase
4
+
5
+ tests Admin::Muck::AccessCodesController
6
+
7
+ should_require_login :index => :get, :bulk => :get, :show => :get,
8
+ :new => :get, :create => :post,
9
+ :edit => :get, :update => :post,
10
+ :destroy => :delete,
11
+ :login_url => '/login'
12
+
13
+ context "access codes controller" do
14
+
15
+ context "logged in not admin" do
16
+ setup do
17
+ @user = Factory(:user)
18
+ activate_authlogic
19
+ login_as @user
20
+ end
21
+ should_require_role('admin', :redirect_url => '/login', :index => :get,
22
+ :bulk => :get, :bulk_create => :post,
23
+ :new => :get, :create => :post,
24
+ :edit => :get, :update => :put,
25
+ :destroy => :delete)
26
+ end
27
+
28
+ context "logged in as admin" do
29
+ setup do
30
+ @admin = Factory(:user)
31
+ @admin_role = Factory(:role, :rolename => 'administrator')
32
+ @admin.roles << @admin_role
33
+ activate_authlogic
34
+ login_as @admin
35
+
36
+ # Add a couple of access codes
37
+ @one = Factory(:access_code)
38
+ @two = Factory(:access_code)
39
+ @access_code = Factory(:access_code)
40
+ end
41
+
42
+ context "GET index" do
43
+ setup do
44
+ get :index
45
+ end
46
+ should_respond_with :success
47
+ should_render_template :index
48
+ end
49
+
50
+ context "GET bulk" do
51
+ setup do
52
+ get :bulk
53
+ end
54
+ should_respond_with :success
55
+ should_render_template 'admin/access_codes/bulk'
56
+ end
57
+
58
+ context "bulk create" do
59
+ setup do
60
+ @code = 'randomcode'
61
+ @emails = 'test@example.com'
62
+ @subject = 'test subject'
63
+ @message = 'test message'
64
+ @params = {:code => 'testcode', :expires_at => Date.new((DateTime.now.year + 2), 10, 10) }
65
+ end
66
+
67
+ context "valid" do
68
+ setup do
69
+ post :bulk_create, {:access_code => @params, :emails => @emails, :subject => @subject, :message => @message}
70
+ end
71
+ should_set_the_flash_to(I18n.translate('muck.users.bulk_access_codes_created', :email_count => 1))
72
+ should_redirect_to("bulk access code page") { bulk_create_admin_access_codes_path }
73
+ end
74
+
75
+ context "valid - no access code provided" do
76
+ setup do
77
+ post :bulk_create, {:access_code => @params.merge(:code => nil), :emails => @emails, :subject => @subject, :message => @message}
78
+ end
79
+ should_set_the_flash_to(I18n.translate('muck.users.bulk_access_codes_created', :email_count => 1))
80
+ should_redirect_to("bulk access code page") { bulk_create_admin_access_codes_path }
81
+ should "set a random code" do
82
+ assert !assigns(:access_code).code.blank?
83
+ end
84
+ end
85
+
86
+ context "no emails provided" do
87
+ setup do
88
+ post :bulk_create, {:access_code => @params, :emails => '', :subject => @subject, :message => @message}
89
+ end
90
+ should_set_the_flash_to(I18n.translate('muck.users.bulk_access_codes_created', :email_count => 0))
91
+ should_redirect_to("bulk access code page") { bulk_create_admin_access_codes_path }
92
+ should "not setup an access code" do
93
+ assert_equal nil, assigns(:access_code)
94
+ end
95
+ end
96
+
97
+ end
98
+
99
+ context "GET new" do
100
+ setup do
101
+ get :new
102
+ end
103
+ should_respond_with :success
104
+ should_render_template :new
105
+ end
106
+
107
+ context "POST to create" do
108
+ setup do
109
+ post :create, :access_code => { :code => 'testcode', :expires_at => Date.new((DateTime.now.year + 2), 10, 10) }
110
+ end
111
+ should_redirect_to("show access code") { admin_access_code_path(assigns(:access_code)) }
112
+ end
113
+
114
+ context "fail on POST to create" do
115
+ setup do
116
+ post :create, :access_code => {:code => nil, :expires_at => Date.new((DateTime.now.year + 2), 10, 10) }
117
+ end
118
+ should_respond_with :success
119
+ should_render_template :new
120
+ should "have errors on access code's 'code' field" do
121
+ assert assigns(:access_code).errors.on(:code)
122
+ end
123
+ end
124
+
125
+ context "GET edit" do
126
+ setup do
127
+ get :edit, :id => @access_code.to_param
128
+ end
129
+ should_respond_with :success
130
+ should_render_template :edit
131
+ end
132
+
133
+ context "PUT to update" do
134
+ setup do
135
+ put :update, :id => @access_code.to_param, :access_code => {:code => 'testcodetoo', :expires_at => Date.new((DateTime.now.year + 2), 10, 10) }
136
+ end
137
+ should_redirect_to("show access code") { admin_access_code_path(assigns(:access_code)) }
138
+ end
139
+
140
+ context "fail on PUT to update" do
141
+ setup do
142
+ put :update, :id => @access_code.to_param, :access_code => {:code => nil, :expires_at => Date.new((DateTime.now.year + 2), 10, 10) }
143
+ end
144
+ should_respond_with :success
145
+ should_render_template :edit
146
+ should "have errors on access code's 'code' field" do
147
+ assert assigns(:access_code).errors.on(:code)
148
+ end
149
+ end
150
+
151
+ context "DELETE to destroy" do
152
+ setup do
153
+ delete :destroy, :id => @access_code.id
154
+ end
155
+ should_redirect_to("show access codes") { admin_access_codes_path }
156
+ should "destroy the access code provided" do
157
+ after_code = AccessCode.find(@access_code.id) rescue nil
158
+ assert_equal nil, after_code
159
+ end
160
+ end
161
+
162
+ end
163
+
164
+ end
165
+
166
+ end