muck-users 0.2.23 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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