Merge lp:~felmas/mvhub/structure_fix into lp:mvhub
- structure_fix
- Merge into trunk_2format
Status: | Merged |
---|---|
Merged at revision: | 602 |
Proposed branch: | lp:~felmas/mvhub/structure_fix |
Merge into: | lp:mvhub |
Diff against target: |
2893 lines (+1895/-538) 28 files modified
app-mvhub/DocumentRoot/cgi-bin/mvhub/admin/structure.pl (+6/-470) app-mvhub/conf/create_sqlite.lib (+69/-6) app-mvhub/conf/sql_delete.lib (+1/-1) app-mvhub/conf/sql_insert.lib (+68/-4) app-mvhub/conf/sql_select.lib (+2/-1) app-mvhub/conf/templates/html/admin.tmpl (+3/-2) app-mvhub/t/debian_packages_installed.t (+1/-0) app-mvhub/t/mech/admin/display_structure_menu.t (+79/-0) app-mvhub/t/mech/admin/process_synonym_form.t (+111/-0) lib-mvhub/lib/MVHub/Headings.pm (+6/-9) lib-mvhub/lib/MVHub/Structure.pm (+471/-0) lib-mvhub/lib/MVHub/Synonyms.pm (+11/-21) lib-mvhub/t/00-setup.t (+8/-1) lib-mvhub/t/Headings/categories.t (+31/-0) lib-mvhub/t/Headings/heading_names.t (+22/-0) lib-mvhub/t/Notifications/set_reminder_level_in_db.t (+1/-1) lib-mvhub/t/Structure/display_category_chooser.t (+70/-0) lib-mvhub/t/Structure/display_structure_menu.t (+60/-0) lib-mvhub/t/Structure/fetch_existing_category_and_dependent_data_from_db.t (+95/-0) lib-mvhub/t/Structure/get_all_headings.t (+19/-0) lib-mvhub/t/Structure/get_all_programs.t (+26/-0) lib-mvhub/t/Structure/is_category_name_taken.t (+33/-0) lib-mvhub/t/Structure/process_category_form.t (+152/-0) lib-mvhub/t/Structure/process_synonym_form.t (+130/-0) lib-mvhub/t/Synonyms/fetch_synonyms_from_db.t (+29/-0) lib-mvhub/t/Utils/clean_cgi_params.t (+4/-2) lib-mvhub/t/lib/TestData.pm (+328/-18) lib-mvhub/t/lib/TestHelper.pm (+59/-2) |
To merge this branch: | bzr merge lp:~felmas/mvhub/structure_fix |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Dan MacNeil | Needs Fixing | ||
Review via email: mp+67376@code.launchpad.net |
Commit message
Description of the change
fix of structure.pl and its related modules
Ferhat Elmas (felmas) wrote : | # |
Dan MacNeil (omacneil) wrote : | # |
120 - my $invocant = shift;
121 - my $class = ref($invocant) || $invocant;
122 -
123 - my $dbh = MVHub::
124 -
125 +
126 + my $class = shift;
127 my $self = { HEADING_
128 -
I'm honestly a little vague about what the original code does. I'm pretty sure it handles calling things in a class context vs a object context, in any event it doesn't need to change ( ? ) for getting the file working again.
Dan MacNeil (omacneil) wrote : | # |
109 [SYNONYM_
110 -DELETE FROM ?
111 +DELETE FROM synonym_stem
Looks like this was broken in the move to SQL::Library which never really tested the synonyms code
Good catch / fix
Dan MacNeil (omacneil) wrote : | # |
basically goods good on code inspection
Ferhat Elmas (felmas) wrote : | # |
120 - my $invocant = shift;
121 - my $class = ref($invocant) || $invocant;
122 -
123 - my $dbh = MVHub::
124 -
125 +
126 + my $class = shift;
127 my $self = { HEADING_
128 -
Line 120-121 is shortened to 126 because $invocant is always sufficient
Line 123 is unnecessary because _fetch_
Dan MacNeil (omacneil) wrote : | # |
this is FYI / thing to think of in future only:
this code and the orginal code put the 'view' (HTML ) in the same file as the 'model' (database) and controller ( Perl glue between them). Ideally, maybe over-engineered, model/view/
Dan MacNeil (omacneil) wrote : | # |
(optional / suggestion )
479 +[005_drop_
482 +[006_create_
maybe slightly clearer as
[005_drop_
[006_create_
also for other table dropping / creating
Ferhat Elmas (felmas) wrote : | # |
I had thought firstly that I should get it worked then separation can be done, I am already here for especially refactor.
After finishing tests, I will do it.
> this is FYI / thing to think of in future only:
>
> this code and the orginal code put the 'view' (HTML ) in the same file as the
> 'model' (database) and controller ( Perl glue between them). Ideally, maybe
> over-engineered, model/view/
> think of keeping them separate.
Dan MacNeil (omacneil) wrote : | # |
(optional / suggested)
734 +# TODO:
[...]
773 +
A lot of these comments can safely be removed. particularly the ones marked DONE. this is only a a suggestion as leaving them in is no worse than the original.
Dan MacNeil (omacneil) wrote : | # |
(suggestion / optional )
81 +# TODO: trouble installing:
782 +#use Text::Capitalize;
remove these lines as they have done nothing for years.
Dan MacNeil (omacneil) wrote : | # |
(stronger suggestion / optional if you really want)
784 +use MVHub::Utils;
785 +use MVHub::
786 +
787 +use MVHub::Common;
788 +use MVHub::Utils::DB;
789 +use MVHub::Headings;
790 +use MVHub::HTML;
791 +use MVHub::Page;
792 +use MVHub::Synonyms;
793 +
794 +use MVHub::
See:
Dan MacNeil (omacneil) wrote : | # |
comment / FYI only
728 === added file 'lib-mvhub/
most of these routines don't:
http://
but this was the case for the original code, so it is no worse.
Also many routines don't sanitize / check $cgi input for evil. This is also the case in the old code, so no worse, no action required for now. Also to get to structure.pl people need to authenticate. Still in long term if their password is compromised or they put in stupid as opposed to evil input we are (potentially) screwed.
Ferhat Elmas (felmas) wrote : | # |
I was wondering the authentication because on mvhub.com I can access
structure.pl which can be dangerous in some weird ways.
On 07/29/2011 07:37 PM, Dan MacNeil wrote:
> comment / FYI only
>
> 728 === added file 'lib-mvhub/
>
> most of these routines don't:
> http://
>
> but this was the case for the original code, so it is no worse.
>
> Also many routines don't sanitize / check $cgi input for evil. This is also the case in the old code, so no worse, no action required for now. Also to get to structure.pl people need to authenticate. Still in long term if their password is compromised or they put in stupid as opposed to evil input we are (potentially) screwed.
Dan MacNeil (omacneil) wrote : | # |
> I had thought firstly that I should get it worked then separation can be done,
> I am already here for especially refactor.
yes. exactly.
Dan MacNeil (omacneil) wrote : | # |
.t files should be executable so they can be run one at a time as scripts.
find . -name '*.t' -and -not -executable
./lib-mvhub/
./lib-mvhub/
./lib-mvhub/
./lib-mvhub/
./lib-mvhub/
./lib-mvhub/
./lib-mvhub/
./lib-mvhub/
# to fix in one go.
find . -name '*.t' -and -not -executable -exec chmod +x {} \;
Dan MacNeil (omacneil) wrote : | # |
1309 +#save config file
1310 +my $config_file = $ENV{MV_
1311 +$ENV{MV_
All this save/restore config file stuff is not needed. %ENV gets reset for each test
Dan MacNeil (omacneil) wrote : | # |
More precisely, we need to set $MV_CONFIG_FILE but we don't need to restore it.
$ENV{MV_
Dan MacNeil (omacneil) wrote : | # |
lib-mvhub/
lib-mvhub/
should probably move to
app-mvhub/
They are more integration tests (test whole app like the user) than they are unit tests (test each sub separately )
These tests will not effect test coverage because the code isn't being instrumented ( modified by Devel::Cover to measure coverage) , the code runs on the webserver, which could be in Siberia
It should not be hard to get test coverage
both routines take a CGI object as a parameter. It is pretty straight forward to dummy up a CGI object to pass in. see:
lib-mvhub/
The problem is that both routines send to stdout instead of returning a value (ugly I know)
Two options:
a. take as given that code is tested by integration tests
b. redirect stdout to a variable and then do pattern matching on that variable to check if the expected data is there.
http://
http://
Dan MacNeil (omacneil) wrote : | # |
Generally should get this stuff from config file $cfg object , see:
perldoc MVHub::
1381 +@site_codes = qw( mvh nsp );
# just use
my $site_code = $CFG->param(
no need to test both sites, code is same.
1382 +$domain = 'testing123.net';
Dan MacNeil (omacneil) wrote : | # |
> 1382 +$domain = 'testing123.net';
# see:
TestHelper:
# aka:
lib-mvhub/
Dan MacNeil (omacneil) wrote : | # |
1623 +is( $result, 0, 'is_category_
1629 +is( $result, 1, 'is_category_
testing two different things, test name should be different. maybe:
$msg='YES is_category_
$msg='NO is_category_
Dan MacNeil (omacneil) wrote : | # |
1384 +$username = 'test';
1385 +$password = 'test';
1658 +$username = 'test';
1659 +$password = 'test';
better:
my ($username, $password)
# now
sub get_admin_
return qw/test test/
}
# later
sub get_admin_
# code to stick temp values in
# /var/www/
# and code to remove them in cleanup
}
advantage is we don't have to change $user/$password in more than one place and can (eventually) get a more secure setup.
- 632. By Ferhat Elmas <<email address hidden>>
-
new test for structure
Ferhat Elmas (felmas) wrote : | # |
In short changes;
I moved tests that use Test::WWW:
I added new unit tests into lib-mvhub/
Now, display_
normal get ok
success get ok
process_
normal get written but doesn't work due to postgre specific query
submit TODO
display_
normal get ok
success get ok
process_
new category get ok
edit category get ok
new category submit TODO
edit category submit TODO
- 633. By Ferhat Elmas <<email address hidden>>
-
non-numeric category id test for edit category mode in process_
category_ form.t - 634. By Ferhat Elmas <<email address hidden>>
-
edited mech/admin/ tests
- 635. By Ferhat Elmas <<email address hidden>>
-
edited lib-mvhub/
t/Structure tests - 636. By Ferhat Elmas <<email address hidden>>
-
merged trunk
- 637. By Ferhat Elmas <<email address hidden>>
-
added TODOs into new broken tests
- 638. By Ferhat Elmas <<email address hidden>>
-
merged trunk
- 639. By Ferhat Elmas <<email address hidden>>
-
refactor of new tests
- 640. By Ferhat Elmas <<email address hidden>>
-
merged trunk
- 641. By Ferhat Elmas <<email address hidden>>
-
removed todos, added new tests
- 642. By Ferhat Elmas <<email address hidden>>
-
merged trunk
- 643. By Ferhat Elmas <<email address hidden>>
-
made executable expand_synonyms.t
- 644. By Ferhat Elmas <<email address hidden>>
-
merged trunk
- 645. By Ferhat Elmas <<email address hidden>>
-
merged trunk
- 646. By Ferhat Elmas <<email address hidden>>
-
merged trunk
- 647. By Ferhat Elmas <<email address hidden>>
-
merged trunk
- 648. By Ferhat Elmas <<email address hidden>>
Preview Diff
1 | === modified file 'app-mvhub/DocumentRoot/cgi-bin/mvhub/admin/structure.pl' |
2 | --- app-mvhub/DocumentRoot/cgi-bin/mvhub/admin/structure.pl 2011-01-01 04:43:01 +0000 |
3 | +++ app-mvhub/DocumentRoot/cgi-bin/mvhub/admin/structure.pl 2011-09-11 23:59:29 +0000 |
4 | @@ -1,72 +1,12 @@ |
5 | #!/usr/bin/perl |
6 | |
7 | -# TODO: |
8 | -# STRUCTURE MENU PAGE |
9 | -# Create. DONE |
10 | -# Beautify & Better Explanations. |
11 | -# Link from Admin Menu Frame. DONE. |
12 | -# CATEGORY SELECTING & EDITING |
13 | -# Selecting Functionality. DONE. |
14 | -# Editing Functionality. DONE |
15 | -# Use template for Form. DONE |
16 | -# Test user errors and responses. DONE. |
17 | -# Explain to the user what an alias is. Distinguish from synonym. |
18 | -# Make sure they're not re-entering a category that already exists (case insensitive): DONE |
19 | -# Possibly order the programs so that selected ones are first? HAVE ORDERED BY AGENCY NAME INSTEAD. |
20 | -# Look into Sharing code with scripts/guide/category_loader.pl |
21 | -# SYNONYM SELECTING & EDITING: |
22 | -# - Create Synonyms.pm from code out of synonym_loader.pl DONE |
23 | -# - Refactor synonym_loader.pl to use MVHub::Synonyms.pm DONE |
24 | -# - Use Synonyms.pm in this script. DONE |
25 | -# - Create template form. DONE |
26 | -# - Recreate synonym_stem table with submitted word column, and load data into it. DONE. |
27 | -# - on dsiegal db. DONE. |
28 | -# - on production db. DONE. |
29 | -# - Create new function & aggregates on production database. DONE. |
30 | -# - Check http://archives.postgresql.org/pgsql-sql/ for answer to question. |
31 | -# - Possibly put in a check to catch (and drop) any duplicated stem within a stem set |
32 | -# - Any limitations on input? |
33 | -# Might want to drop at least commas, and possibly only keep alphas, hyphens, apostrophes. |
34 | -# HEADINGS |
35 | -# Everything. TODO. |
36 | -# |
37 | -# MISC |
38 | -# Possibly, edit the Admin Home Page with the same links as in the top frame, but also explanations. |
39 | -# Check other TODOs. |
40 | -# Change Common to get only a specific version of FormBuilder: DONE |
41 | -# Add spell checking. Probably want to refactor how we incorporate it (here as well as in rest of application). |
42 | -# Test on IE |
43 | -# Throw out scripts/guide/add_category.pl. |
44 | -# Document IN PROGRESS |
45 | -# Usability Testing |
46 | - |
47 | use strict; |
48 | use warnings; |
49 | |
50 | use CGI; |
51 | -use CGI::Carp; |
52 | -use DBI; |
53 | - |
54 | -# TODO: trouble installing: |
55 | -#use Text::Capitalize; |
56 | - |
57 | + |
58 | +use MVHub::Structure; |
59 | use MVHub::Utils; |
60 | -use MVHub::HTMLTemplateUtils; |
61 | - |
62 | -use MVHub::Common; |
63 | -use MVHub::Utils::DB; |
64 | -use MVHub::Headings; |
65 | -use MVHub::HTML; |
66 | -use MVHub::Page; |
67 | -use MVHub::Synonyms; |
68 | - |
69 | -use MVHub::Wrap::ConfigSimple; |
70 | - |
71 | -my $cfg = MVHub::Wrap::ConfigSimple->new(); |
72 | -my $template_dir = $cfg->param('ABSOLUTE_PATH.template_html_dir'); |
73 | -my $EDIT_SYNONYMS_TEMPLATE = "$template_dir/edit_synonyms.tmpl"; |
74 | -my $EDIT_CATEGORIES_TEMPLATE = "$template_dir/edit_categories_template"; |
75 | -my $STRUCTURE_MENU_TEMPLATE = "$template_dir/structure_menu.tmpl"; |
76 | |
77 | { |
78 | my $cgi = CGI->new(); |
79 | @@ -74,422 +14,18 @@ |
80 | my $mode = $cgi->param('mode'); |
81 | $cgi->delete('mode'); |
82 | if ( !$mode || $mode eq 'structure_menu' ) { |
83 | - display_structure_menu($cgi); |
84 | + MVHub::Structure::display_structure_menu($cgi); |
85 | } |
86 | elsif ( $mode eq 'category_chooser' ) { |
87 | - display_category_chooser($cgi); |
88 | + MVHub::Structure::display_category_chooser($cgi); |
89 | } |
90 | elsif ( $mode eq 'edit_category' ) { |
91 | - process_category_form($cgi); |
92 | + MVHub::Structure::process_category_form($cgi); |
93 | } |
94 | elsif ( $mode eq 'edit_synonyms' ) { |
95 | - process_synonym_form($cgi); |
96 | + MVHub::Structure::process_synonym_form($cgi); |
97 | } |
98 | else { |
99 | MVHub::Utils::assert( 0, "Unknown mode requested of $0: $mode" ); |
100 | } |
101 | } |
102 | - |
103 | -sub process_synonym_form { |
104 | - my $cgi = shift; |
105 | - |
106 | - if ( $cgi->param('synonyms') ) { |
107 | - |
108 | - # Form was submitted; update the database |
109 | - my $synonyms_string = $cgi->param('synonyms'); |
110 | - my @synonyms = split( '\n', $synonyms_string ); |
111 | - Synonyms::submit_synonyms_to_db(@synonyms); |
112 | - my $redirect_url |
113 | - = $ENV{SCRIPT_NAME} . '?mode=structure_menu&success=1'; |
114 | - print $cgi->redirect($redirect_url); |
115 | - exit(0); |
116 | - } |
117 | - else { |
118 | - |
119 | - # Display the form with pre-existing values from database |
120 | - my @synonyms = Synonyms::fetch_synonyms_from_db(); |
121 | - my $synonyms_string = join( "\n", @synonyms ); |
122 | - |
123 | - # FYI: Using Cgi::Formbuilder is overkill for a form with just one field, |
124 | - # so we've just layed out the form explicitly in the template. |
125 | - HTMLTemplateUtils::format_template( |
126 | - filename => $EDIT_SYNONYMS_TEMPLATE, |
127 | - param_href => { |
128 | - synonyms => $synonyms_string, |
129 | - rows => ( @synonyms + 2 ) |
130 | - }, |
131 | - print => 1, |
132 | - doctype => 1 |
133 | - ); |
134 | - } |
135 | -} |
136 | - |
137 | -sub display_structure_menu { |
138 | - my $cgi = shift; |
139 | - MVHub::HTMLTemplateUtils::format_template( |
140 | - filename => $STRUCTURE_MENU_TEMPLATE, |
141 | - param_href => { $cgi->Vars() }, |
142 | - print => 1, |
143 | - doctype => 1 |
144 | - ); |
145 | -} |
146 | - |
147 | -sub display_category_chooser { |
148 | - my $cgi = shift; |
149 | - my $headings = new Headings(); |
150 | - my @heading_names = $headings->heading_names(); |
151 | - |
152 | - my @output = ('<br>'); |
153 | - if ( $cgi->param('success') ) { |
154 | - push( @output, |
155 | - CGI::p('<font color="red">Your changes have been saved.</font>') |
156 | - ); |
157 | - } |
158 | - push( @output, |
159 | - '<p>', |
160 | - '<button onclick=', |
161 | - qq|location.href="$ENV{SCRIPT_NAME}?mode=edit_category"|, |
162 | - '> <strong>Create a New Category</strong></button>', |
163 | - '</p>', |
164 | - '<p>', |
165 | - '<strong>or Click a Category to Edit:</strong>', |
166 | - '</p>' ); |
167 | - |
168 | - my $url = $ENV{SCRIPT_NAME} . '?mode=edit_category&category_id='; |
169 | - foreach (@heading_names) { |
170 | - push( @output, "<h2>$_</h2>" ); |
171 | - my $categories_aref = $headings->categories($_); |
172 | - |
173 | - # Copied from Guide.pm. Consider refactoring. |
174 | - # Generate an html table of category links |
175 | - my @links; |
176 | - foreach (@$categories_aref) { |
177 | - my $link = $url . $_->{category_id}; |
178 | - my $label = CGI::escapeHTML( $_->{category_name} ); |
179 | - |
180 | - # add space around forward slashes so a label like |
181 | - # "Translating/Interpreting" will wrap nicely |
182 | - $label =~ s|\s*/\s*| / |g; |
183 | - push( @links, CGI::a( { href => $link }, $label ) ); |
184 | - } |
185 | - |
186 | - my $table = HTML::make_html_table( |
187 | - columns => 4, |
188 | - content_aref => \@links, |
189 | - table_attributes => 'width="100%" cellspacing="5"' |
190 | - ); |
191 | - push( @output, $table ); |
192 | - } |
193 | - print( $cgi->header('text/html'), |
194 | - $cgi->start_html( |
195 | - -style => { -src => '/guide/styles/admin.css' }, |
196 | - -title => 'Directory Structure Administration' |
197 | - ), |
198 | - join( "\n", @output ), |
199 | - $cgi->end_html() |
200 | - ); |
201 | -} |
202 | - |
203 | -sub process_category_form { |
204 | - my $cgi = shift; |
205 | - my $category_id = $cgi->param('category_id'); |
206 | - if ( defined $category_id ) { |
207 | - MVHub::Utils::assert( $category_id !~ /\D/, |
208 | - 'Category id must be numeric only' ); |
209 | - } |
210 | - |
211 | - my $preloaded_values_href; |
212 | - my $form = make_category_editing_form($cgi); |
213 | - |
214 | - if ( $form->submitted() ) { |
215 | - if ( $form->validate() && validate_more($form) ) { |
216 | - submit_category_form_data_to_db( scalar $form->field() ); |
217 | - my $redirect_url |
218 | - = $ENV{SCRIPT_NAME} . '?mode=structure_menu&success=1'; |
219 | - print $cgi->redirect($redirect_url); |
220 | - exit(0); |
221 | - } |
222 | - else { |
223 | - |
224 | - # TODO: add announcement? |
225 | - } |
226 | - } |
227 | - elsif ($category_id) { |
228 | - $preloaded_values_href |
229 | - = fetch_existing_category_and_dependent_data_from_db( |
230 | - $category_id); |
231 | - } |
232 | - print $form->render( header => 1, values => $preloaded_values_href ); |
233 | -} |
234 | - |
235 | -# Returns a CGI::Formbuilder object representing our form. The form is blank (i.e. |
236 | -# the fields are defined, but are not pre-populated with any data.) |
237 | -# This CGI::Formbuilder object has no associated page header. |
238 | -sub make_category_editing_form { |
239 | - my ($cgi) = @_; |
240 | - |
241 | - my %category_field_defs = ( |
242 | - category_id => { type => 'hidden' }, |
243 | - category_name => { required => 1 }, |
244 | - aliases => { |
245 | - type => 'textarea', |
246 | - rows => 3, |
247 | - comment => 'Optional. One per line.' |
248 | - }, |
249 | - headings => { |
250 | - type => 'checkbox', |
251 | - options => get_all_headings(), |
252 | - columns => 3, |
253 | - required => 1, |
254 | - comment => 'Select one or more.' |
255 | - }, |
256 | - programs => { |
257 | - type => 'checkbox', |
258 | - options => get_all_programs(), |
259 | - columns => 1, |
260 | - comment => "Optional. Alternatively, you can assign categories" |
261 | - . " to programs via their program forms." |
262 | - } |
263 | - ); |
264 | - |
265 | - my $form = MVHub::Common::prepare_form( |
266 | - form_attributes_href => { |
267 | - name => 'category_editor_form', |
268 | - params => $cgi, |
269 | - |
270 | -# TODO: listing the columns here is only while we're not using an html template, |
271 | -# so that CGI:FB knows what order to display 'em in: |
272 | -# fields => [qw/category_name aliases headings programs/] |
273 | -# TODO: remove the above 3 lines. |
274 | - template => $EDIT_CATEGORIES_TEMPLATE |
275 | - }, |
276 | - fields_href => \%category_field_defs |
277 | - ); |
278 | - |
279 | - return $form; |
280 | -} |
281 | - |
282 | -# Returns a reference to an array of headings, e.g.: |
283 | -# [ "Arts/Culture/Entertainment", "Financial Education/Credit", ... ] |
284 | -sub get_all_headings { |
285 | - my $dbh = MVHub::Utils::DB::get_dbh(); |
286 | - my $sql = MVHub::Utils::DB::get_sql_select_statement( |
287 | - 'HEADING_X_HEADING_NAME'); |
288 | - my $headings_aref = $dbh->selectcol_arrayref($sql); |
289 | - return $headings_aref; |
290 | -} |
291 | - |
292 | -# Returns a reference to an array of program hashrefs, e.g.: |
293 | -# [ |
294 | -# { 12345 => 'Youth Volleyball (YMCA)' }, |
295 | -# { 156745 => 'Building Blocks (North Shore Arc)' }, |
296 | -# ... |
297 | -# ] |
298 | -sub get_all_programs { |
299 | - my $dbh = MVHub::Utils::DB::get_dbh(); |
300 | - |
301 | - my $sql = MVHub::Utils::DB::get_sql_select_statement( |
302 | - 'PROGRAM_X_PROGRAM_AGENCY_ID'); |
303 | - |
304 | - my $result_aref = $dbh->selectall_arrayref($sql); |
305 | - |
306 | - # see end of 'perldoc -f map' on why the '+' in the following: |
307 | - my @headings = map( +{ $_->[0] => $_->[1] }, @$result_aref ); |
308 | - return \@headings; |
309 | -} |
310 | - |
311 | -# The return statement tells all. |
312 | -sub fetch_existing_category_and_dependent_data_from_db { |
313 | - my $category_id = shift; |
314 | - my $dbh = MVHub::Utils::DB::get_dbh(); |
315 | - |
316 | - my $sql = MVHub::Utils::DB::get_sql_select_statement( |
317 | - 'CATEGORY_X_CATEGORY_NAME'); |
318 | - my @bind_values = ($category_id); |
319 | - |
320 | - my @result |
321 | - = @{ $dbh->selectall_arrayref( $sql, { Slice => {} }, @bind_values ) |
322 | - }; |
323 | - my $category_name = $result[0]->{category_name}; |
324 | - |
325 | - $sql = MVHub::Utils::DB::get_sql_select_statement('ALIAS_X_ALIAS_NAME'); |
326 | - my $aliases_aref |
327 | - = $dbh->selectcol_arrayref( $sql, { Slice => {} }, $category_id ); |
328 | - my $aliases = join( "\n", @$aliases_aref ); |
329 | - |
330 | - $sql = MVHub::Utils::DB::get_sql_select_statement( |
331 | - 'HEADING_CATEGORY_X_HEADING_NAME'); |
332 | - my $headings_aref |
333 | - = $dbh->selectcol_arrayref( $sql, { Slice => {} }, $category_id ); |
334 | - MVHub::Utils::assert( @$headings_aref, |
335 | - "Expected at least one heading for this category (#$category_id)" ); |
336 | - |
337 | - $sql = MVHub::Utils::DB::get_sql_select_statement( |
338 | - 'PROGRAM_CATEGORY_X_PROGRAM_ID'); |
339 | - my $programs_aref |
340 | - = $dbh->selectcol_arrayref( $sql, { Slice => {} }, $category_id ); |
341 | - return { |
342 | - category_name => $category_name, |
343 | - aliases => $aliases, |
344 | - headings => $headings_aref, |
345 | - programs => $programs_aref |
346 | - }; |
347 | -} |
348 | - |
349 | -sub submit_category_form_data_to_db { |
350 | - my $values_href = shift; |
351 | - |
352 | -# Pre-processing data destined for database here: |
353 | -# TODO: get T:C installed or remove this line |
354 | -#$values_href->{category_name} = Text::Capitalize::$values_href->{category_name}; |
355 | - |
356 | - my $dbh = MVHub::Utils::DB::get_dbh(); |
357 | - $dbh->begin_work(); |
358 | - |
359 | -# If we have a category id, we must be updating an existing category. |
360 | -# In this case, in addition to updating the category record, we need to |
361 | -# get rid of the dependent alias, heading_category and program_category records |
362 | -# the user wants removed, update any changed ones, and add any new ones. |
363 | -# That's a lot of work. The easiest way is to just delete the existing |
364 | -# category record, whcih will cascade to delete the dependent records (because |
365 | -# of the way the foreign keys are defined on the those tables). |
366 | -# Then we insert everything, just as if we were creating a new category. The only |
367 | -# difference is that for an update we re-use the existing category_id, and |
368 | -# for a new category we'll make a new one. |
369 | - if ( $values_href->{category_id} ) { |
370 | - my $sql = MVHub::Utils::DB::get_sql_delete_statement( |
371 | - 'CATEGORY_X_CATEGORY_ID'); |
372 | - $dbh->do( $sql, undef, $values_href->{category_id} ); |
373 | - } |
374 | - else { |
375 | - $values_href->{category_id} |
376 | - = MVHub::Utils::DB::get_next_in_sequence( $dbh, |
377 | - 'category_id_sequence' ); |
378 | - } |
379 | - insert_category_and_dependent_data( dbh => $dbh, %$values_href ); |
380 | - $dbh->commit(); |
381 | -} |
382 | - |
383 | -sub insert_category_and_dependent_data { |
384 | - my %args = @_; |
385 | - my $dbh = delete $args{dbh}; |
386 | - my $category_id = delete $args{category_id}; |
387 | - my $category_name = delete $args{category_name}; |
388 | - my $aliases_string = delete $args{aliases}; |
389 | - my $heading_names_aref = delete $args{headings}; |
390 | - my $program_ids_aref = delete $args{programs}; |
391 | - MVHub::Utils::assert( ( scalar keys %args ) == 0, |
392 | - "Unknown arguments: @{[%args]}" ); |
393 | - |
394 | - MVHub::Utils::DB::insert_one_record( |
395 | - dbh => $dbh, |
396 | - table => 'category', |
397 | - values_href => { |
398 | - 'category_name' => $category_name, |
399 | - 'stems_name' => Common::get_stems($category_name), |
400 | - 'category_id' => $category_id |
401 | - } |
402 | - ); |
403 | - |
404 | - if ($aliases_string) { |
405 | - |
406 | - # TODO: are we guaranteed that the line separator is a \n ? |
407 | - my @aliases = split( '\n', $aliases_string ); |
408 | - |
409 | - foreach my $alias (@aliases) { |
410 | - $alias = MVHub::Utils::trim($alias); |
411 | - next unless $alias; # ignore blank lines |
412 | - Common::insert_one_record( |
413 | - dbh => $dbh, |
414 | - table => 'alias', |
415 | - values_href => { |
416 | - 'category_id' => $category_id, |
417 | - 'alias_name' => $alias, |
418 | - 'stems_name' => Common::get_stems($alias) |
419 | - } |
420 | - ); |
421 | - } |
422 | - } |
423 | - |
424 | - foreach my $heading_name (@$heading_names_aref) { |
425 | - Common::insert_one_record( |
426 | - dbh => $dbh, |
427 | - table => 'heading_category', |
428 | - values_href => { |
429 | - 'category_id' => $category_id, |
430 | - 'heading_name' => $heading_name |
431 | - } |
432 | - ); |
433 | - } |
434 | - |
435 | - foreach my $program_id (@$program_ids_aref) { |
436 | - Common::insert_one_record( |
437 | - dbh => $dbh, |
438 | - table => 'program_category', |
439 | - values_href => { |
440 | - 'category_id' => $category_id, |
441 | - 'program_id' => $program_id |
442 | - } |
443 | - ); |
444 | - } |
445 | -} |
446 | - |
447 | -# This is the place for error checking that can't be done within |
448 | -# CGI::FormBuilder->validate(), e.g.: |
449 | -# - complex validations that require access to other variables |
450 | -# - validations that need to produce a custom error message |
451 | -# Returns 0 iff any validation fails, supplying an error message |
452 | -# for each failed validation in the custom_error-category_name template |
453 | -# variable on the form. |
454 | -sub validate_more { |
455 | - my $form = shift; |
456 | - my $return_val = 1; |
457 | - |
458 | - if (is_category_name_taken( |
459 | - category_name => $form->field('category_name'), |
460 | - category_id => $form->field('category_id') |
461 | - ) |
462 | - ) |
463 | - { |
464 | - my $msg = "The category name you entered is " |
465 | - . "already being used by another category. Please enter a different one:"; |
466 | - $form->tmpl_param( 'custom_error-category_name', $msg ); |
467 | - |
468 | - $return_val = 0; |
469 | - } |
470 | - |
471 | - return $return_val; |
472 | -} |
473 | - |
474 | -# Returns true iff the given category name is already in use |
475 | -# (without regard to case) in the database by another category. If a |
476 | -# a category_id argument is supplied, then any record with that ID |
477 | -# will be excluded from the search. Returns false otherwise. |
478 | -sub is_category_name_taken { |
479 | - my %args = @_; |
480 | - my $category_name = delete $args{'category_name'}; |
481 | - my $category_id = delete $args{'category_id'}; |
482 | - MVHub::Utils::assert( defined $category_name && $category_name ne "", |
483 | - "Missing category_name argument" ); |
484 | - MVHub::Utils::assert( ( scalar keys %args ) == 0, |
485 | - "Unknown arguments: @{[%args]}" ); |
486 | - my $dbh = MVHub::Utils::DB::get_dbh( $ENV{MV_CONFIG_FILE} ); |
487 | - |
488 | - # The SELECT EXISTS (SELECT 1 ...) syntax is generally faster than the |
489 | - # SELECT count(*) syntax, since the former only scans until it finds |
490 | - # the first match. |
491 | - my @bind_variables = ( lc($category_name) ); |
492 | - my $sql = MVHub::Utils::DB::get_sql_select_statement( |
493 | - 'CATEGORY_X_EXISTS_ONE_CATEGORY_NAME'); |
494 | - |
495 | - if ($category_id) { |
496 | - @bind_variables = ( lc($category_name), $category_id ); |
497 | - $sql = MVHub::Utils::DB::get_sql_select_statement( |
498 | - 'CATEGORY_X_EXISTS_ONE_CATEGORY_NAME_NOT_ID'); |
499 | - } |
500 | - |
501 | - my @row |
502 | - = $dbh->selectall_arrayref( $sql, { Slice => {} }, @bind_variables ); |
503 | - |
504 | - return ( $row[0] ); |
505 | -} |
506 | |
507 | === modified file 'app-mvhub/conf/create_sqlite.lib' |
508 | --- app-mvhub/conf/create_sqlite.lib 2011-08-25 15:05:33 +0000 |
509 | +++ app-mvhub/conf/create_sqlite.lib 2011-09-11 23:59:29 +0000 |
510 | @@ -1,4 +1,4 @@ |
511 | -[001_drop_agency] |
512 | +[001_drop_agency_table] |
513 | DROP TABLE IF EXISTS agency; |
514 | |
515 | -- This: |
516 | @@ -7,7 +7,7 @@ |
517 | -- postgresql CREATE TABLE agency |
518 | -- but for existing tests it doesn't have to |
519 | |
520 | -[002_create_agency] |
521 | +[002_create_agency_table] |
522 | CREATE TABLE agency ( |
523 | agency_id INTEGER PRIMARY KEY, |
524 | last_updated DATE not null, |
525 | @@ -54,15 +54,14 @@ |
526 | date_created DATE, |
527 | quick_login_passwd TEXT |
528 | ); |
529 | -SQL |
530 | |
531 | -[003_drop_program] |
532 | +[003_drop_program_table] |
533 | DROP TABLE IF EXISTS program; |
534 | |
535 | -[004_create_program] |
536 | +[004_create_program_table] |
537 | CREATE TABLE program ( |
538 | program_id INTEGER PRIMARY KEY, |
539 | - agency_id INTEGER not null REFERENCES agency ON DELETE CASCADE, |
540 | + agency_id INTEGER not null REFERENCES agency(agency_id) ON DELETE CASCADE, |
541 | last_updated DATE not null, |
542 | hidden_reason TEXT, |
543 | |
544 | @@ -130,3 +129,67 @@ |
545 | |
546 | CONSTRAINT area_check CHECK(((area_data IS not null) AND area_data <> '') or area_type = 'EVERYWHERE') |
547 | ); |
548 | + |
549 | +[005_drop_category_table] |
550 | + DROP TABLE IF EXISTS category; |
551 | + |
552 | +[006_create_category_table] |
553 | +CREATE TABLE category ( |
554 | + category_id INTEGER PRIMARY KEY, |
555 | + category_name TEXT not null CHECK(category_name <> '') UNIQUE, |
556 | + stems_name TEXT not null CHECK(stems_name <> '') |
557 | +); |
558 | + |
559 | +[007_drop_program_category_table] |
560 | + DROP TABLE IF EXISTS program_category; |
561 | + |
562 | +[008_create_program_category_table] |
563 | +CREATE TABLE program_category ( |
564 | + category_id INTEGER not null REFERENCES category(category_id) ON DELETE CASCADE, |
565 | + program_id INTEGER not null REFERENCES program(program_id) on DELETE CASCADE, |
566 | + |
567 | + PRIMARY KEY(category_id, program_id) |
568 | +); |
569 | + |
570 | +[009_drop_alias_table] |
571 | + DROP TABLE IF EXISTS alias; |
572 | + |
573 | +[010_create_alias_table] |
574 | +CREATE TABLE alias ( |
575 | + category_id INTEGER not null REFERENCES category(category_id) ON DELETE CASCADE, |
576 | + alias_name TEXT not null CHECK(alias_name <> ''), |
577 | + stems_name TEXT not null CHECK(stems_name <> ''), |
578 | + |
579 | + PRIMARY KEY(category_id, alias_name) |
580 | +); |
581 | + |
582 | +[011_drop_synonym_stem_table] |
583 | + DROP TABLE IF EXISTS synonym_stem; |
584 | + |
585 | +[012_create_synonym_stem_table] |
586 | +CREATE TABLE synonym_stem ( |
587 | + synonym_id INTEGER not null, |
588 | + word_stem TEXT not null CHECK(word_stem <> ''), |
589 | + submitted_word TEXT not null CHECK(submitted_word <> ''), |
590 | + |
591 | + PRIMARY KEY(synonym_id, word_stem) |
592 | +); |
593 | + |
594 | +[013_drop_heading_table] |
595 | + DROP TABLE IF EXISTS heading; |
596 | + |
597 | +[014_create_heading_table] |
598 | +CREATE TABLE heading ( |
599 | + heading_name TEXT PRIMARY KEY |
600 | +); |
601 | + |
602 | +[015_drop_heading_category_table] |
603 | + DROP TABLE IF EXISTS heading_category; |
604 | + |
605 | +[016_create_heading_category_table] |
606 | +CREATE TABLE heading_category ( |
607 | + category_id INTEGER not null REFERENCES category(category_id) ON DELETE CASCADE, |
608 | + heading_name TEXT not null REFERENCES heading(heading_name) ON UPDATE CASCADE ON DELETE CASCADE, |
609 | + |
610 | + PRIMARY KEY(category_id, heading_name) |
611 | +); |
612 | |
613 | === modified file 'app-mvhub/conf/sql_delete.lib' |
614 | --- app-mvhub/conf/sql_delete.lib 2010-11-26 02:34:44 +0000 |
615 | +++ app-mvhub/conf/sql_delete.lib 2011-09-11 23:59:29 +0000 |
616 | @@ -44,4 +44,4 @@ |
617 | WHERE program_id = ? |
618 | |
619 | [SYNONYM_STEM_X_ALL] |
620 | -DELETE FROM ? |
621 | +DELETE FROM synonym_stem |
622 | |
623 | === modified file 'app-mvhub/conf/sql_insert.lib' |
624 | --- app-mvhub/conf/sql_insert.lib 2010-06-29 18:02:33 +0000 |
625 | +++ app-mvhub/conf/sql_insert.lib 2011-09-11 23:59:29 +0000 |
626 | @@ -24,16 +24,30 @@ |
627 | 'contact_first_name','contact_last_name','contact_phone','contact_email_available' |
628 | ); |
629 | |
630 | +[CATEGORY_X_REQUIRED_FIELDS] |
631 | +INSERT INTO category |
632 | +( |
633 | + category_id, |
634 | + category_name, |
635 | + stems_name |
636 | +) |
637 | +VALUES |
638 | +( |
639 | + ?, |
640 | + ?, |
641 | + ? |
642 | +); |
643 | + |
644 | [PROGRAM_CATEGORY_X_REQUIRED_FIELDS] |
645 | INSERT INTO program_category |
646 | ( |
647 | - program_id, |
648 | - category_id |
649 | + program_id, |
650 | + category_id |
651 | ) |
652 | VALUES |
653 | ( |
654 | - ?, |
655 | - ? |
656 | + ?, |
657 | + ? |
658 | ); |
659 | |
660 | [PROGRAM_X_REQUIRED_FIELDS] |
661 | @@ -69,3 +83,53 @@ |
662 | 'area_type','online_registration','area_type','area_data','resource library','meeting space', |
663 | 'contact_first_name','contact_last_name','contact_phone', 'contact_email_available' |
664 | ); |
665 | + |
666 | +[ALIAS_X_REQUIRED_FIELDS] |
667 | +INSERT INTO alias |
668 | +( |
669 | + category_id, |
670 | + alias_name, |
671 | + stems_name |
672 | +) |
673 | +VALUES |
674 | +( |
675 | + ?, |
676 | + ?, |
677 | + ? |
678 | +); |
679 | + |
680 | +[SYNONYM_STEM_X_REQUIRED_FIELDS] |
681 | +INSERT INTO synonym_stem |
682 | +( |
683 | + synonym_id, |
684 | + word_stem, |
685 | + submitted_word |
686 | +) |
687 | +VALUES |
688 | +( |
689 | + ?, |
690 | + ?, |
691 | + ? |
692 | +); |
693 | + |
694 | +[HEADING_X_REQUIRED_FIELDS] |
695 | +INSERT INTO heading |
696 | +( |
697 | + heading_name |
698 | +) |
699 | +VALUES |
700 | +( |
701 | + ? |
702 | +); |
703 | + |
704 | +[HEADING_CATEGORY_X_REQUIRED_FIELDS] |
705 | +INSERT INTO heading_category |
706 | +( |
707 | + category_id, |
708 | + heading_name |
709 | +) |
710 | +VALUES |
711 | +( |
712 | + ?, |
713 | + ? |
714 | +); |
715 | |
716 | === modified file 'app-mvhub/conf/sql_select.lib' |
717 | --- app-mvhub/conf/sql_select.lib 2011-07-12 20:50:24 +0000 |
718 | +++ app-mvhub/conf/sql_select.lib 2011-09-11 23:59:29 +0000 |
719 | @@ -629,6 +629,7 @@ |
720 | WHERE lower(category_name) = ? |
721 | AND category_id <> ? |
722 | ) |
723 | + |
724 | [CATEGORY_X_IN_CATEGORY_NAME] |
725 | SELECT category_name |
726 | FROM category |
727 | @@ -958,7 +959,7 @@ |
728 | ORDER BY categories DESC, subq.program_and_agency_name |
729 | |
730 | [PROGRAM_X_PROGRAM_AGENCY_ID] |
731 | -SELECT p.program_id, a.agency_name || ': ' || program_name |
732 | +SELECT p.program_id, a.agency_name || ': ' || p.program_name |
733 | AS agency_program_name |
734 | FROM agency a,program p |
735 | WHERE a.agency_id = p.agency_id |
736 | |
737 | === modified file 'app-mvhub/conf/templates/html/admin.tmpl' |
738 | --- app-mvhub/conf/templates/html/admin.tmpl 2011-06-29 15:01:03 +0000 |
739 | +++ app-mvhub/conf/templates/html/admin.tmpl 2011-09-11 23:59:29 +0000 |
740 | @@ -35,8 +35,9 @@ |
741 | <a target="main_frame" href="/html/admin/home.shtml">Home</a> | |
742 | <a target="main_frame" href="/cgi-bin/mvhub/admin/admin_reports.pl">Reports</a> | |
743 | <a target="main_frame" href="/cgi-bin/mvhub/agency_form.pl">Add a New Agency</a> | |
744 | - <a target="main_frame" href="/cgi-bin/mvhub/admin/call_manager.pl">Call Manager</a> |
745 | - </td> |
746 | + <a target="main_frame" href="/cgi-bin/mvhub/admin/call_manager.pl">Call Manager</a> | |
747 | + <a target="main_frame" href="/cgi-bin/mvhub/admin/structure.pl">Structure</a> |
748 | + </td> |
749 | <td align="right"><a href="/cgi-bin/mvhub/logout.pl" target="_top" onclick="alert('You must close all your browser windows to fully logout.')">Log out</a><br/> |
750 | </td></tr> |
751 | </table> |
752 | |
753 | === modified file 'app-mvhub/t/debian_packages_installed.t' |
754 | --- app-mvhub/t/debian_packages_installed.t 2011-08-15 08:04:54 +0000 |
755 | +++ app-mvhub/t/debian_packages_installed.t 2011-09-11 23:59:29 +0000 |
756 | @@ -47,6 +47,7 @@ |
757 | 'libtest-mockobject-perl' => [], |
758 | 'libtest-nowarnings-perl' => [], |
759 | 'libtest-warn-perl' => [], |
760 | + 'libtest-trap-perl' => [], |
761 | 'libtext-template-perl' => [], |
762 | 'liburi-perl' => [], |
763 | 'perltidy' => [], |
764 | |
765 | === added file 'app-mvhub/t/mech/admin/display_structure_menu.t' |
766 | --- app-mvhub/t/mech/admin/display_structure_menu.t 1970-01-01 00:00:00 +0000 |
767 | +++ app-mvhub/t/mech/admin/display_structure_menu.t 2011-09-11 23:59:29 +0000 |
768 | @@ -0,0 +1,79 @@ |
769 | +#!/usr/bin/perl |
770 | + |
771 | +use strict; |
772 | +use warnings; |
773 | + |
774 | +use Test::Deep; |
775 | +use Test::More tests => 20; |
776 | +use Test::WWW::Mechanize; |
777 | + |
778 | +use MVHub::Wrap::ConfigSimple; |
779 | +use TestHelper; |
780 | + |
781 | +my ( $cfg, $site_code, $website, $address, $mech ); |
782 | +my ( $base, $mode, $success, $param_message ); |
783 | +my ( $username, $password ) = TestHelper::get_admin_username_password(); |
784 | + |
785 | +$cfg = MVHub::Wrap::ConfigSimple->new(); |
786 | +$site_code = $cfg->param('SITE.website_code'); |
787 | +$website = TestHelper::get_test_website_name($site_code); |
788 | + |
789 | +$base = '/cgi-bin/mvhub/admin/structure.pl'; |
790 | +$mode = 'mode=structure_menu'; |
791 | +$success = 'success=1'; |
792 | + |
793 | +$mech = Test::WWW::Mechanize->new(); |
794 | +$mech->credentials( $username, $password ); |
795 | + |
796 | +$address = "http://$website$base"; |
797 | +$param_message = 'without mode and succes parameters'; |
798 | +check_page_title_and_links( $mech, $address, $param_message ); |
799 | + |
800 | +$address = "$base?$mode"; |
801 | +$param_message = 'with mode parameter'; |
802 | +check_page_title_and_links( $mech, $address, $param_message ); |
803 | + |
804 | +$address = "$base?$success"; |
805 | +$param_message = 'with success parameter'; |
806 | +check_page_title_and_links( $mech, $address, $param_message ); |
807 | + |
808 | +$address = "$base?$mode&$success"; |
809 | +$param_message = 'with mode and success parameters'; |
810 | +check_page_title_and_links( $mech, $address, $param_message ); |
811 | + |
812 | +sub check_page_title_and_links { |
813 | + |
814 | + my $mech = shift; |
815 | + my $address = shift; |
816 | + my $param_message = shift; |
817 | + my $title = 'Add/Edit Synonyms'; |
818 | + my $success_message = 'Your changes have been saved'; |
819 | + my ( @real_links, @content_links ); |
820 | + |
821 | + @content_links = (); |
822 | + @real_links = ( |
823 | + '/all/css/admin.css', |
824 | + '/html/admin/help.shtml#search_config', |
825 | + '/cgi-bin/mvhub/admin/structure.pl?mode=category_chooser', |
826 | + '/cgi-bin/mvhub/admin/structure.pl?mode=edit_synonyms' |
827 | + ); |
828 | + |
829 | + $mech->get_ok( $address, "page is got successfully $param_message" ); |
830 | + $mech->title_is( $title, "title is correct $param_message" ); |
831 | + foreach ( $mech->followable_links() ) { |
832 | + push @content_links, $_->url(); |
833 | + } |
834 | + if ( $param_message =~ /success/ ) { |
835 | + $mech->text_contains( $success_message, |
836 | + "success message is show successfully $param_message" ); |
837 | + } |
838 | + else { |
839 | + $mech->text_lacks( $success_message, |
840 | + "success message is not shown $param_message" ); |
841 | + } |
842 | + |
843 | + cmp_deeply( \@content_links, \@real_links, |
844 | + "all links found are correct $param_message" ); |
845 | + $mech->page_links_ok("all links are checked $param_message"); |
846 | + |
847 | +} |
848 | |
849 | === added file 'app-mvhub/t/mech/admin/process_synonym_form.t' |
850 | --- app-mvhub/t/mech/admin/process_synonym_form.t 1970-01-01 00:00:00 +0000 |
851 | +++ app-mvhub/t/mech/admin/process_synonym_form.t 2011-09-11 23:59:29 +0000 |
852 | @@ -0,0 +1,111 @@ |
853 | +#!/usr/bin/perl |
854 | + |
855 | +use strict; |
856 | +use warnings; |
857 | + |
858 | +use Test::Deep; |
859 | +use Test::More tests => 13; |
860 | +use Test::WWW::Mechanize; |
861 | + |
862 | +use MVHub::Wrap::ConfigSimple; |
863 | +use TestHelper; |
864 | + |
865 | +my ( $cfg, $site_code, $website, $uri, $title, $mech ); |
866 | +my ( $username, $password ) = TestHelper::get_admin_username_password(); |
867 | +my ( $synonyms, $new_synonym, $success_message ); |
868 | + |
869 | +$cfg = MVHub::Wrap::ConfigSimple->new(); |
870 | +$site_code = $cfg->param('SITE.website_code'); |
871 | +$website = TestHelper::get_test_website_name($site_code); |
872 | +$uri = '/cgi-bin/mvhub/admin/structure.pl?mode=edit_synonyms'; |
873 | +$title = 'Add/Edit Synonyms'; |
874 | +$new_synonym = 'zoo animal park'; |
875 | +$synonyms = <<END; |
876 | +ADD ADHD HADD |
877 | +alcohol drinking drunk |
878 | +assist help |
879 | +cessation quit |
880 | +child children kid youth |
881 | +class lesson |
882 | +computer technology internet |
883 | +counseling therapy |
884 | +detoxification detox |
885 | +disabled handicapped |
886 | +drug substance |
887 | +elder elderly senior |
888 | +fitness exercise |
889 | +health medical healthcare |
890 | +infant baby |
891 | +job career vocation employment |
892 | +literacy reading writing language |
893 | +marital marriage |
894 | +methadone heroine |
895 | +money finance |
896 | +nurse rna |
897 | +nutrition nutritionist |
898 | +pregnant pregnancy |
899 | +register registration |
900 | +teen adolescent |
901 | +television tv |
902 | +tenant rent renter rental |
903 | +tobacco smoking |
904 | +utility electricity energy fuel heat gas oil |
905 | +vote voter elect |
906 | +END |
907 | +$success_message = 'Your changes have been saved'; |
908 | + |
909 | +$mech = Test::WWW::Mechanize->new(); |
910 | +$mech->credentials( $username, $password ); |
911 | + |
912 | +#first get the synonyms in the database and test their existence and links |
913 | +$mech->get_ok( "http://$website$uri", |
914 | + 'page is got successfully before any processing' ); |
915 | +$mech->title_is( $title, 'title is correct before any processing' ); |
916 | +check_links($mech); |
917 | +$mech->text_contains( $synonyms, |
918 | + 'all synonyms are shown correctly before any processing' ); |
919 | +$mech->text_lacks( $new_synonym, |
920 | + 'new synonym is not shown before any processing' ); |
921 | + |
922 | +#second submit new synonym and then check whether it can be shown |
923 | +$mech->form_number(1); #form number starts from 1 |
924 | +$mech->field( 'synonyms', "$synonyms\n$new_synonym" ); |
925 | +$mech->submit(); |
926 | +$mech->text_contains( $success_message, |
927 | + 'new synonym is added, redirect is successful' ); |
928 | + |
929 | +#third get the synonyms again to see new synonym and delete it |
930 | +$mech->get_ok( "http://$website$uri", |
931 | + 'page is got successfully after addition of new synonym' ); |
932 | +$mech->text_contains( "$synonyms$new_synonym", |
933 | + 'new synonym is shown successfully after addition' ); |
934 | +$mech->form_number(1); |
935 | +$mech->field( 'synonyms', $synonyms ); |
936 | +$mech->submit(); |
937 | +$mech->text_contains( $success_message, |
938 | + 'new synonym is deleted, redirect is successful' ); |
939 | + |
940 | +#finally get the synonyms to see whether new synonyms is deleted |
941 | +$mech->get_ok( "http://$website$uri", |
942 | + 'page is got successfully after deletion of new synonym' ); |
943 | +$mech->text_contains( $synonyms, |
944 | + 'all synonyms are shown correctly after deletion' ); |
945 | +$mech->text_lacks( $new_synonym, 'new synonyms is deleted and not shown' ); |
946 | + |
947 | +sub check_links { |
948 | + |
949 | + my $mech = shift; |
950 | + my ( @real_links, @content_links ); |
951 | + |
952 | + @content_links = (); |
953 | + @real_links |
954 | + = ( '/all/css/admin.css', '/html/admin/help.shtml#search_config', ); |
955 | + foreach ( $mech->followable_links() ) { |
956 | + push @content_links, $_->url(); |
957 | + } |
958 | + |
959 | + cmp_deeply( \@content_links, \@real_links, |
960 | + 'all links found are correct' ); |
961 | + $mech->page_links_ok('all links are checked'); |
962 | + |
963 | +} |
964 | |
965 | === modified file 'lib-mvhub/lib/MVHub/Headings.pm' |
966 | --- lib-mvhub/lib/MVHub/Headings.pm 2010-09-17 16:42:35 +0000 |
967 | +++ lib-mvhub/lib/MVHub/Headings.pm 2011-09-11 23:59:29 +0000 |
968 | @@ -8,8 +8,6 @@ |
969 | |
970 | use MVHub::Common; |
971 | |
972 | -our ($VERSION) = '$Revision: 1215 $' =~ /([.\d]+)/; |
973 | - |
974 | =head2 new() |
975 | |
976 | Initializes a Heading object from the database. |
977 | @@ -17,13 +15,9 @@ |
978 | =cut |
979 | |
980 | sub new { |
981 | - my $invocant = shift; |
982 | - my $class = ref($invocant) || $invocant; |
983 | - |
984 | - my $dbh = MVHub::Utils::DB::get_dbh(); |
985 | - |
986 | + |
987 | + my $class = shift; |
988 | my $self = { HEADING_CATEGORIES_HREF => _fetch_heading_categories() }; |
989 | - |
990 | bless( $self, $class ); |
991 | return $self; |
992 | } |
993 | @@ -76,7 +70,7 @@ |
994 | # } |
995 | sub _fetch_heading_categories { |
996 | |
997 | - my $dbh = MVHub::Utils::DB::get_dbh(); |
998 | + my $dbh = MVHub::Utils::DB::get_dbh( $ENV{MV_CONFIG_FILE} ); |
999 | my $sql = MVHub::Utils::DB::get_sql_select_statement( |
1000 | "CATEGORY_HEADING_CATEGORY_X_FETCH_HEADING_CATEGORY"); |
1001 | |
1002 | @@ -89,3 +83,6 @@ |
1003 | } |
1004 | return \%heading_categories; |
1005 | } |
1006 | + |
1007 | +# all good modules return 1 |
1008 | +1; |
1009 | |
1010 | === added file 'lib-mvhub/lib/MVHub/Structure.pm' |
1011 | --- lib-mvhub/lib/MVHub/Structure.pm 1970-01-01 00:00:00 +0000 |
1012 | +++ lib-mvhub/lib/MVHub/Structure.pm 2011-09-11 23:59:29 +0000 |
1013 | @@ -0,0 +1,471 @@ |
1014 | +package MVHub::Structure; |
1015 | + |
1016 | +# TODO: |
1017 | +# STRUCTURE MENU PAGE |
1018 | +# Beautify & Better Explanations. |
1019 | +# CATEGORY SELECTING & EDITING |
1020 | +# Possibly order the programs so that selected ones are first? HAVE ORDERED BY AGENCY NAME INSTEAD. |
1021 | +# Look into Sharing code with scripts/guide/category_loader.pl |
1022 | +# SYNONYM SELECTING & EDITING: |
1023 | +# - Check http://archives.postgresql.org/pgsql-sql/ for answer to question. |
1024 | +# - Possibly put in a check to catch (and drop) any duplicated stem within a stem set |
1025 | +# - Any limitations on input? |
1026 | +# Might want to drop at least commas, and possibly only keep alphas, hyphens, apostrophes. |
1027 | +# HEADINGS |
1028 | +# Everything. TODO. |
1029 | +# |
1030 | +# MISC |
1031 | +# Possibly, edit the Admin Home Page with the same links as in the top frame, but also explanations. |
1032 | +# Check other TODOs. |
1033 | +# Add spell checking. Probably want to refactor how we incorporate it (here as well as in rest of application). |
1034 | +# Test on IE |
1035 | +# Throw out scripts/guide/add_category.pl. |
1036 | +# Document IN PROGRESS |
1037 | +# Usability Testing |
1038 | + |
1039 | +use strict; |
1040 | +use warnings; |
1041 | + |
1042 | +use CGI; |
1043 | +use CGI::Carp; |
1044 | +use DBI; |
1045 | + |
1046 | +use MVHub::Common; |
1047 | +use MVHub::Headings; |
1048 | +use MVHub::HTML; |
1049 | +use MVHub::HTMLTemplateUtils; |
1050 | +use MVHub::Page; |
1051 | +use MVHub::Synonyms; |
1052 | +use MVHub::Utils; |
1053 | +use MVHub::Utils::DB; |
1054 | +use MVHub::Wrap::ConfigSimple; |
1055 | + |
1056 | +use base 'Exporter'; |
1057 | +our @EXPORT_OK = qw( |
1058 | + display_structure_menu |
1059 | + display_category_chooser |
1060 | + process_category_form |
1061 | + process_synonym_form |
1062 | + make_categort_editing_form |
1063 | + get_all_headings |
1064 | + get_all_programs |
1065 | + fetch_existing_category_and_dependent_data_from_db |
1066 | + submit_category_form_data_to_db |
1067 | + insert_category_and_dependent_data |
1068 | + validate_more |
1069 | + is_category_name_taken |
1070 | +); |
1071 | + |
1072 | +my $cfg = MVHub::Wrap::ConfigSimple->new(); |
1073 | +my $template_dir = $cfg->param('ABSOLUTE_PATH.template_html_dir'); |
1074 | +my $EDIT_SYNONYMS_TEMPLATE = "$template_dir/edit_synonyms.tmpl"; |
1075 | +my $EDIT_CATEGORIES_TEMPLATE = "$template_dir/edit_categories.tmpl"; |
1076 | +my $STRUCTURE_MENU_TEMPLATE = "$template_dir/structure_menu.tmpl"; |
1077 | + |
1078 | +sub process_synonym_form { |
1079 | + my $cgi = shift; |
1080 | + |
1081 | + if ( $cgi->param('synonyms') ) { |
1082 | + |
1083 | + # Form was submitted; update the database |
1084 | + my $synonyms_string = $cgi->param('synonyms'); |
1085 | + my @synonyms = split( '\n', $synonyms_string ); |
1086 | + MVHub::Synonyms::submit_synonyms_to_db(@synonyms); |
1087 | + my $redirect_url |
1088 | + = $ENV{SCRIPT_NAME} . '?mode=structure_menu&success=1'; |
1089 | + print $cgi->redirect($redirect_url); |
1090 | + exit(0); |
1091 | + } |
1092 | + else { |
1093 | + |
1094 | + # Display the form with pre-existing values from database |
1095 | + my @synonyms = MVHub::Synonyms::fetch_synonyms_from_db(); |
1096 | + my $synonyms_string = join( "\n", @synonyms ); |
1097 | + |
1098 | + # FYI: Using Cgi::Formbuilder is overkill for a form with just one field, |
1099 | + # so we've just layed out the form explicitly in the template. |
1100 | + MVHub::HTMLTemplateUtils::format_template( |
1101 | + filename => $EDIT_SYNONYMS_TEMPLATE, |
1102 | + param_href => { |
1103 | + synonyms => $synonyms_string, |
1104 | + rows => ( @synonyms + 2 ) |
1105 | + }, |
1106 | + print => 1, |
1107 | + doctype => 1 |
1108 | + ); |
1109 | + } |
1110 | +} |
1111 | + |
1112 | +sub display_structure_menu { |
1113 | + my $cgi = shift; |
1114 | + MVHub::HTMLTemplateUtils::format_template( |
1115 | + filename => $STRUCTURE_MENU_TEMPLATE, |
1116 | + param_href => { $cgi->Vars() }, |
1117 | + print => 1, |
1118 | + doctype => 1 |
1119 | + ); |
1120 | +} |
1121 | + |
1122 | +sub display_category_chooser { |
1123 | + my $cgi = shift; |
1124 | + my $headings = MVHub::Headings->new(); |
1125 | + my @heading_names = $headings->heading_names(); |
1126 | + |
1127 | + my @output = ('<br>'); |
1128 | + if ( $cgi->param('success') ) { |
1129 | + push( @output, |
1130 | + CGI::p('<font color="red">Your changes have been saved.</font>') |
1131 | + ); |
1132 | + } |
1133 | + push( @output, |
1134 | + '<p>', |
1135 | + '<button onclick=', |
1136 | + qq|location.href="$ENV{SCRIPT_NAME}?mode=edit_category"|, |
1137 | + '> <strong>Create a New Category</strong></button>', |
1138 | + '</p>', |
1139 | + '<p>', |
1140 | + '<strong>or Click a Category to Edit:</strong>', |
1141 | + '</p>' ); |
1142 | + |
1143 | + my $url = $ENV{SCRIPT_NAME} . '?mode=edit_category&category_id='; |
1144 | + foreach (@heading_names) { |
1145 | + push( @output, "<h2>$_</h2>" ); |
1146 | + my $categories_aref = $headings->categories($_); |
1147 | + |
1148 | + # Copied from Guide.pm. Consider refactoring. |
1149 | + # Generate an html table of category links |
1150 | + my @links; |
1151 | + foreach (@$categories_aref) { |
1152 | + my $link = $url . $_->{category_id}; |
1153 | + my $label = CGI::escapeHTML( $_->{category_name} ); |
1154 | + |
1155 | + # add space around forward slashes so a label like |
1156 | + # "Translating/Interpreting" will wrap nicely |
1157 | + $label =~ s|\s*/\s*| / |g; |
1158 | + push( @links, CGI::a( { href => $link }, $label ) ); |
1159 | + } |
1160 | + |
1161 | + my $table = MVHub::HTML::make_html_table( |
1162 | + columns => 4, |
1163 | + content_aref => \@links, |
1164 | + table_attributes => 'width="100%" cellspacing="5"' |
1165 | + ); |
1166 | + push( @output, $table ); |
1167 | + } |
1168 | + |
1169 | + print( $cgi->header('text/html'), |
1170 | + $cgi->start_html( |
1171 | + -style => { -src => '/all/css/admin.css' }, |
1172 | + -title => 'Directory Structure Administration' |
1173 | + ), |
1174 | + join( "\n", @output ), |
1175 | + $cgi->end_html() |
1176 | + ); |
1177 | +} |
1178 | + |
1179 | +sub process_category_form { |
1180 | + my $cgi = shift; |
1181 | + my $category_id = $cgi->param('category_id'); |
1182 | + |
1183 | + if ( defined $category_id ) { |
1184 | + MVHub::Utils::assert( $category_id !~ /\D/, |
1185 | + 'Category id must be numeric only' ); |
1186 | + } |
1187 | + |
1188 | + my $preloaded_values_href; |
1189 | + my $form = make_category_editing_form($cgi); |
1190 | + |
1191 | + if ( $form->submitted() ) { |
1192 | + if ( $form->validate() && validate_more($form) ) { |
1193 | + submit_category_form_data_to_db( scalar $form->field() ); |
1194 | + my $redirect_url |
1195 | + = $ENV{SCRIPT_NAME} . '?mode=structure_menu&success=1'; |
1196 | + print $cgi->redirect($redirect_url); |
1197 | + exit(0); |
1198 | + } |
1199 | + else { |
1200 | + |
1201 | + # TODO: add announcement? |
1202 | + } |
1203 | + } |
1204 | + elsif ($category_id) { |
1205 | + $preloaded_values_href |
1206 | + = fetch_existing_category_and_dependent_data_from_db( |
1207 | + $category_id); |
1208 | + } |
1209 | + print $form->render( header => 1, values => $preloaded_values_href ); |
1210 | +} |
1211 | + |
1212 | +# Returns a CGI::Formbuilder object representing our form. The form is blank (i.e. |
1213 | +# the fields are defined, but are not pre-populated with any data.) |
1214 | +# This CGI::Formbuilder object has no associated page header. |
1215 | +sub make_category_editing_form { |
1216 | + my ($cgi) = @_; |
1217 | + |
1218 | + my %category_field_defs = ( |
1219 | + category_id => { type => 'hidden' }, |
1220 | + category_name => { required => 1 }, |
1221 | + aliases => { |
1222 | + type => 'textarea', |
1223 | + rows => 3, |
1224 | + comment => 'Optional. One per line.' |
1225 | + }, |
1226 | + headings => { |
1227 | + type => 'checkbox', |
1228 | + options => get_all_headings(), |
1229 | + columns => 3, |
1230 | + required => 1, |
1231 | + comment => 'Select one or more.' |
1232 | + }, |
1233 | + programs => { |
1234 | + type => 'checkbox', |
1235 | + options => get_all_programs(), |
1236 | + columns => 1, |
1237 | + comment => "Optional. Alternatively, you can assign categories" |
1238 | + . " to programs via their program forms." |
1239 | + } |
1240 | + ); |
1241 | + |
1242 | + my $form = MVHub::Common::prepare_form( |
1243 | + form_attributes_href => { |
1244 | + name => 'category_editor_form', |
1245 | + params => $cgi, |
1246 | + |
1247 | +# TODO: listing the columns here is only while we're not using an html template, |
1248 | +# so that CGI:FB knows what order to display 'em in: |
1249 | +# fields => [qw/category_name aliases headings programs/] |
1250 | +# TODO: remove the above 3 lines. |
1251 | + template => $EDIT_CATEGORIES_TEMPLATE |
1252 | + }, |
1253 | + fields_href => \%category_field_defs |
1254 | + ); |
1255 | + |
1256 | + return $form; |
1257 | +} |
1258 | + |
1259 | +# Returns a reference to an array of headings, e.g.: |
1260 | +# [ "Arts/Culture/Entertainment", "Financial Education/Credit", ... ] |
1261 | +sub get_all_headings { |
1262 | + my $dbh = MVHub::Utils::DB::get_dbh( $ENV{MV_CONFIG_FILE} ); |
1263 | + my $sql = MVHub::Utils::DB::get_sql_select_statement( |
1264 | + 'HEADING_X_HEADING_NAME'); |
1265 | + my $headings_aref = $dbh->selectcol_arrayref($sql); |
1266 | + return $headings_aref; |
1267 | +} |
1268 | + |
1269 | +# Returns a reference to an array of program hashrefs, e.g.: |
1270 | +# [ |
1271 | +# { 12345 => 'Youth Volleyball (YMCA)' }, |
1272 | +# { 156745 => 'Building Blocks (North Shore Arc)' }, |
1273 | +# ... |
1274 | +# ] |
1275 | +sub get_all_programs { |
1276 | + my $dbh = MVHub::Utils::DB::get_dbh( $ENV{MV_CONFIG_FILE} ); |
1277 | + |
1278 | + my $sql = MVHub::Utils::DB::get_sql_select_statement( |
1279 | + 'PROGRAM_X_PROGRAM_AGENCY_ID'); |
1280 | + |
1281 | + my $result_aref = $dbh->selectall_arrayref($sql); |
1282 | + |
1283 | + # see end of 'perldoc -f map' on why the '+' in the following: |
1284 | + my @headings = map( +{ $_->[0] => $_->[1] }, @$result_aref ); |
1285 | + return \@headings; |
1286 | +} |
1287 | + |
1288 | +# The return statement tells all. |
1289 | +sub fetch_existing_category_and_dependent_data_from_db { |
1290 | + my $category_id = shift; |
1291 | + my $dbh = MVHub::Utils::DB::get_dbh( $ENV{MV_CONFIG_FILE} ); |
1292 | + |
1293 | + my $sql = MVHub::Utils::DB::get_sql_select_statement( |
1294 | + 'CATEGORY_X_CATEGORY_NAME'); |
1295 | + my @bind_values = ($category_id); |
1296 | + |
1297 | + my @result |
1298 | + = @{ $dbh->selectall_arrayref( $sql, { Slice => {} }, @bind_values ) |
1299 | + }; |
1300 | + my $category_name = $result[0]->{category_name}; |
1301 | + |
1302 | + $sql = MVHub::Utils::DB::get_sql_select_statement('ALIAS_X_ALIAS_NAME'); |
1303 | + my $aliases_aref |
1304 | + = $dbh->selectcol_arrayref( $sql, { Slice => {} }, $category_id ); |
1305 | + my $aliases = join( "\n", @$aliases_aref ); |
1306 | + |
1307 | + $sql = MVHub::Utils::DB::get_sql_select_statement( |
1308 | + 'HEADING_CATEGORY_X_HEADING_NAME'); |
1309 | + my $headings_aref |
1310 | + = $dbh->selectcol_arrayref( $sql, { Slice => {} }, $category_id ); |
1311 | + MVHub::Utils::assert( @$headings_aref, |
1312 | + "Expected at least one heading for this category (#$category_id)" ); |
1313 | + |
1314 | + $sql = MVHub::Utils::DB::get_sql_select_statement( |
1315 | + 'PROGRAM_CATEGORY_X_PROGRAM_ID'); |
1316 | + my $programs_aref |
1317 | + = $dbh->selectcol_arrayref( $sql, { Slice => {} }, $category_id ); |
1318 | + return { |
1319 | + category_name => $category_name, |
1320 | + aliases => $aliases, |
1321 | + headings => $headings_aref, |
1322 | + programs => $programs_aref |
1323 | + }; |
1324 | +} |
1325 | + |
1326 | +sub submit_category_form_data_to_db { |
1327 | + my $values_href = shift; |
1328 | + |
1329 | +# Pre-processing data destined for database here: |
1330 | +# TODO: get T:C installed or remove this line |
1331 | +#$values_href->{category_name} = Text::Capitalize::$values_href->{category_name}; |
1332 | + |
1333 | + my $dbh = MVHub::Utils::DB::get_dbh( $ENV{MV_CONFIG_FILE} ); |
1334 | + $dbh->begin_work(); |
1335 | + |
1336 | +# If we have a category id, we must be updating an existing category. |
1337 | +# In this case, in addition to updating the category record, we need to |
1338 | +# get rid of the dependent alias, heading_category and program_category records |
1339 | +# the user wants removed, update any changed ones, and add any new ones. |
1340 | +# That's a lot of work. The easiest way is to just delete the existing |
1341 | +# category record, whcih will cascade to delete the dependent records (because |
1342 | +# of the way the foreign keys are defined on the those tables). |
1343 | +# Then we insert everything, just as if we were creating a new category. The only |
1344 | +# difference is that for an update we re-use the existing category_id, and |
1345 | +# for a new category we'll make a new one. |
1346 | + if ( $values_href->{category_id} ) { |
1347 | + my $sql = MVHub::Utils::DB::get_sql_delete_statement( |
1348 | + 'CATEGORY_X_CATEGORY_ID'); |
1349 | + $dbh->do( $sql, undef, $values_href->{category_id} ); |
1350 | + } |
1351 | + else { |
1352 | + $values_href->{category_id} |
1353 | + = MVHub::Utils::DB::get_next_in_sequence( $dbh, |
1354 | + 'category_id_sequence' ); |
1355 | + } |
1356 | + insert_category_and_dependent_data( dbh => $dbh, %$values_href ); |
1357 | + $dbh->commit(); |
1358 | +} |
1359 | + |
1360 | +sub insert_category_and_dependent_data { |
1361 | + my %args = @_; |
1362 | + my $dbh = delete $args{dbh}; |
1363 | + my $category_id = delete $args{category_id}; |
1364 | + my $category_name = delete $args{category_name}; |
1365 | + my $aliases_string = delete $args{aliases}; |
1366 | + my $heading_names_aref = delete $args{headings}; |
1367 | + my $program_ids_aref = delete $args{programs}; |
1368 | + MVHub::Utils::assert( ( scalar keys %args ) == 0, |
1369 | + "Unknown arguments: @{[%args]}" ); |
1370 | + |
1371 | + MVHub::Utils::DB::insert_one_record( |
1372 | + dbh => $dbh, |
1373 | + table => 'category', |
1374 | + values_href => { |
1375 | + 'category_name' => $category_name, |
1376 | + 'stems_name' => MVHub::Common::get_stems($category_name), |
1377 | + 'category_id' => $category_id |
1378 | + } |
1379 | + ); |
1380 | + |
1381 | + if ($aliases_string) { |
1382 | + |
1383 | + # TODO: are we guaranteed that the line separator is a \n ? |
1384 | + my @aliases = split( '\n', $aliases_string ); |
1385 | + |
1386 | + foreach my $alias (@aliases) { |
1387 | + $alias = MVHub::Utils::trim($alias); |
1388 | + next unless $alias; # ignore blank lines |
1389 | + MVHub::Utils::DB::insert_one_record( |
1390 | + dbh => $dbh, |
1391 | + table => 'alias', |
1392 | + values_href => { |
1393 | + 'category_id' => $category_id, |
1394 | + 'alias_name' => $alias, |
1395 | + 'stems_name' => MVHub::Common::get_stems($alias) |
1396 | + } |
1397 | + ); |
1398 | + } |
1399 | + } |
1400 | + |
1401 | + foreach my $heading_name (@$heading_names_aref) { |
1402 | + MVHub::Utils::DB::insert_one_record( |
1403 | + dbh => $dbh, |
1404 | + table => 'heading_category', |
1405 | + values_href => { |
1406 | + 'category_id' => $category_id, |
1407 | + 'heading_name' => $heading_name |
1408 | + } |
1409 | + ); |
1410 | + } |
1411 | + |
1412 | + foreach my $program_id (@$program_ids_aref) { |
1413 | + MVHub::Utils::DB::insert_one_record( |
1414 | + dbh => $dbh, |
1415 | + table => 'program_category', |
1416 | + values_href => { |
1417 | + 'category_id' => $category_id, |
1418 | + 'program_id' => $program_id |
1419 | + } |
1420 | + ); |
1421 | + } |
1422 | +} |
1423 | + |
1424 | +# This is the place for error checking that can't be done within |
1425 | +# CGI::FormBuilder->validate(), e.g.: |
1426 | +# - complex validations that require access to other variables |
1427 | +# - validations that need to produce a custom error message |
1428 | +# Returns 0 iff any validation fails, supplying an error message |
1429 | +# for each failed validation in the custom_error-category_name template |
1430 | +# variable on the form. |
1431 | +sub validate_more { |
1432 | + my $form = shift; |
1433 | + my $return_val = 1; |
1434 | + |
1435 | + if (is_category_name_taken( |
1436 | + category_name => $form->field('category_name'), |
1437 | + category_id => $form->field('category_id') |
1438 | + ) |
1439 | + ) |
1440 | + { |
1441 | + my $msg = "The category name you entered is " |
1442 | + . "already being used by another category. Please enter a different one:"; |
1443 | + $form->tmpl_param( 'custom_error-category_name', $msg ); |
1444 | + |
1445 | + $return_val = 0; |
1446 | + } |
1447 | + |
1448 | + return $return_val; |
1449 | +} |
1450 | + |
1451 | +# Returns true iff the given category name is already in use |
1452 | +# (without regard to case) in the database by another category. If a |
1453 | +# a category_id argument is supplied, then any record with that ID |
1454 | +# will be excluded from the search. Returns false otherwise. |
1455 | +sub is_category_name_taken { |
1456 | + my %args = @_; |
1457 | + my $category_name = delete $args{'category_name'}; |
1458 | + my $category_id = delete $args{'category_id'}; |
1459 | + MVHub::Utils::assert( defined $category_name && $category_name ne "", |
1460 | + "Missing category_name argument" ); |
1461 | + MVHub::Utils::assert( ( scalar keys %args ) == 0, |
1462 | + "Unknown arguments: @{[%args]}" ); |
1463 | + my $dbh = MVHub::Utils::DB::get_dbh( $ENV{MV_CONFIG_FILE} ); |
1464 | + |
1465 | + # The SELECT EXISTS (SELECT 1 ...) syntax is generally faster than the |
1466 | + # SELECT count(*) syntax, since the former only scans until it finds |
1467 | + # the first match. |
1468 | + my @bind_variables = ( lc($category_name) ); |
1469 | + my $sql = MVHub::Utils::DB::get_sql_select_statement( |
1470 | + 'CATEGORY_X_EXISTS_ONE_CATEGORY_NAME'); |
1471 | + |
1472 | + if ($category_id) { |
1473 | + @bind_variables = ( lc($category_name), $category_id ); |
1474 | + $sql = MVHub::Utils::DB::get_sql_select_statement( |
1475 | + 'CATEGORY_X_EXISTS_ONE_CATEGORY_NAME_NOT_ID'); |
1476 | + } |
1477 | + |
1478 | + my @row = $dbh->selectrow_array( $sql, { Slice => {} }, @bind_variables ); |
1479 | + |
1480 | + return ( $row[0] ); |
1481 | +} |
1482 | + |
1483 | +# all good modules return 1; |
1484 | +1; |
1485 | |
1486 | === modified file 'lib-mvhub/lib/MVHub/Synonyms.pm' |
1487 | --- lib-mvhub/lib/MVHub/Synonyms.pm 2010-09-13 00:58:44 +0000 |
1488 | +++ lib-mvhub/lib/MVHub/Synonyms.pm 2011-09-11 23:59:29 +0000 |
1489 | @@ -3,22 +3,10 @@ |
1490 | use strict; |
1491 | use warnings; |
1492 | |
1493 | -# --------------------------------------------------------------- |
1494 | -# Loads synonyms from the $SYNONYM_FILE (defined below) into the |
1495 | -# database. |
1496 | -# |
1497 | -# This script must be run from the installed site (i.e. not from |
1498 | -# your cvs projects path). |
1499 | -# |
1500 | -# Each line in the synonym file is a space-delimited list of one-word |
1501 | -# synonyms |
1502 | -# |
1503 | -# Since the $SYNONYM_TABLE (below) has no dependents (i.e. |
1504 | -# other tables that reference its data), this script may be re-run on |
1505 | -# on an existing site. |
1506 | -# The $SYNONYM_SEQUENCE (below) is reset to its initial value. |
1507 | -# |
1508 | -# --------------------------------------------------------------- |
1509 | +use base 'Exporter'; |
1510 | +our @EXPORT_OK = qw( |
1511 | + fetch_synonyms_from_db |
1512 | +); |
1513 | |
1514 | use MVHub::Common; |
1515 | |
1516 | @@ -34,7 +22,7 @@ |
1517 | # Returns a list of lines, where each line is a space delimited list of |
1518 | # one word synonyms of each other. |
1519 | sub fetch_synonyms_from_db { |
1520 | - my $dbh = MVHub::Utils::DB::get_dbh(); |
1521 | + my $dbh = MVHub::Utils::DB::get_dbh( $ENV{MV_CONFIG_FILE} ); |
1522 | |
1523 | my $sql = MVHub::Utils::DB::get_sql_select_statement( |
1524 | 'SYNONYM_STEM_X_SUBMITTED_WORDS'); |
1525 | @@ -50,17 +38,19 @@ |
1526 | # one word synonyms of each other. |
1527 | # Submits them into the database table, $SYNONYM_TABLE. |
1528 | # Dies on any database error. |
1529 | + |
1530 | +# **** DESTROYS ***** existing table |
1531 | + |
1532 | sub submit_synonyms_to_db { |
1533 | my @synonym_lines = @_; |
1534 | - my $dbh = MVHub::Utils::DB::get_dbh(); |
1535 | + my $dbh = MVHub::Utils::DB::get_dbh( $ENV{MV_CONFIG_FILE} ); |
1536 | $dbh->{AutoCommit} = 0; |
1537 | |
1538 | - my @bind_variables = ($SYNONYM_TABLE); |
1539 | my $sql |
1540 | = MVHub::Utils::DB::get_sql_delete_statement('SYNONYM_STEM_X_ALL'); |
1541 | - $dbh->do( $sql, undef, @bind_variables ); |
1542 | + $dbh->do( $sql, undef, () ); |
1543 | |
1544 | - @bind_variables = ( $SYNONYM_SEQUENCE, $SYNONYM_SEQUENCE_INIT_VAL ); |
1545 | + my @bind_variables = ( $SYNONYM_SEQUENCE, $SYNONYM_SEQUENCE_INIT_VAL ); |
1546 | $sql = MVHub::Utils::DB::get_sql_select_statement('SETVAL_X_SYNONYM_SEQ'); |
1547 | $dbh->do( $sql, undef, @bind_variables ); |
1548 | |
1549 | |
1550 | === modified file 'lib-mvhub/t/00-setup.t' |
1551 | --- lib-mvhub/t/00-setup.t 2010-10-08 19:44:05 +0000 |
1552 | +++ lib-mvhub/t/00-setup.t 2011-09-11 23:59:29 +0000 |
1553 | @@ -9,7 +9,14 @@ |
1554 | |
1555 | use MVHub::Utils::DB qw/ get_dbh /; |
1556 | |
1557 | -use TestData qw/@agency @program/; |
1558 | +use TestData qw/@agency |
1559 | + @program |
1560 | + @category |
1561 | + @program_category |
1562 | + @alias |
1563 | + @synonym_stem |
1564 | + @heading |
1565 | + @heading_category/; |
1566 | use TestHelper qw/ add_test_data create_sqlite_db /; |
1567 | |
1568 | eval ' use Test::NoWarnings; '; |
1569 | |
1570 | === modified file 'lib-mvhub/t/GuideSearch/expand_synonyms.t' (properties changed: -x to +x) |
1571 | === added directory 'lib-mvhub/t/Headings' |
1572 | === added file 'lib-mvhub/t/Headings/categories.t' |
1573 | --- lib-mvhub/t/Headings/categories.t 1970-01-01 00:00:00 +0000 |
1574 | +++ lib-mvhub/t/Headings/categories.t 2011-09-11 23:59:29 +0000 |
1575 | @@ -0,0 +1,31 @@ |
1576 | +#!/usr/bin/perl |
1577 | + |
1578 | +use strict; |
1579 | +use warnings; |
1580 | + |
1581 | +use Test::Deep; |
1582 | +use Test::More tests => 3; |
1583 | + |
1584 | +use MVHub::Headings; |
1585 | + |
1586 | +use_ok('MVHub::Headings'); |
1587 | + |
1588 | +$ENV{MV_CONFIG_FILE} = $ENV{MV_TEST_CONFIG_FILE}; |
1589 | + |
1590 | +my $headings = MVHub::Headings->new(); |
1591 | +isa_ok( $headings, 'MVHub::Headings' ); |
1592 | + |
1593 | +my $heading_name = 'Arts/Culture/Entertainment'; |
1594 | +my $real_categories = [ |
1595 | + { category_id => 1006, category_name => 'Arts, Youth' }, |
1596 | + { category_id => 1003, category_name => 'Arts/Entertainment' }, |
1597 | + { category_id => 1001, category_name => 'Cultural Heritage' }, |
1598 | + { category_id => 1007, category_name => 'Culture' }, |
1599 | + { category_id => 1005, category_name => 'Museum' }, |
1600 | + { category_id => 1002, category_name => 'Music' }, |
1601 | + { category_id => 1004, category_name => 'Theater/Performance Art' } |
1602 | +]; |
1603 | + |
1604 | +my $categories = $headings->categories($heading_name); |
1605 | + |
1606 | +cmp_deeply( $categories, $real_categories, 'category arrays are same' ); |
1607 | |
1608 | === added file 'lib-mvhub/t/Headings/heading_names.t' |
1609 | --- lib-mvhub/t/Headings/heading_names.t 1970-01-01 00:00:00 +0000 |
1610 | +++ lib-mvhub/t/Headings/heading_names.t 2011-09-11 23:59:29 +0000 |
1611 | @@ -0,0 +1,22 @@ |
1612 | +#!/usr/bin/perl |
1613 | + |
1614 | +use strict; |
1615 | +use warnings; |
1616 | + |
1617 | +use Test::Deep; |
1618 | +use Test::More tests => 3; |
1619 | + |
1620 | +use MVHub::Headings; |
1621 | + |
1622 | +use_ok('MVHub::Headings'); |
1623 | + |
1624 | +$ENV{MV_CONFIG_FILE} = $ENV{MV_TEST_CONFIG_FILE}; |
1625 | + |
1626 | +my $headings = MVHub::Headings->new(); |
1627 | +isa_ok( $headings, 'MVHub::Headings' ); |
1628 | + |
1629 | +my $real_heading_names |
1630 | + = [ 'Arts/Culture/Entertainment', 'City/Town Services' ]; |
1631 | +my @heading_names = $headings->heading_names(); |
1632 | + |
1633 | +is_deeply( \@heading_names, $real_heading_names, 'heading arrays are same' ); |
1634 | |
1635 | === modified file 'lib-mvhub/t/Notifications/set_reminder_level_in_db.t' |
1636 | --- lib-mvhub/t/Notifications/set_reminder_level_in_db.t 2010-10-16 00:29:43 +0000 |
1637 | +++ lib-mvhub/t/Notifications/set_reminder_level_in_db.t 2011-09-11 23:59:29 +0000 |
1638 | @@ -64,7 +64,7 @@ |
1639 | 'PROGRAM_X_REMINDERS_SENT' ); |
1640 | is_deeply( |
1641 | $dbh->selectcol_arrayref("SELECT reminders_sent FROM program"), |
1642 | - [ 1, 2, 3, 4 ], |
1643 | + [ 1, 2, 3, 4, 4 ], |
1644 | $test_message |
1645 | ); |
1646 | |
1647 | |
1648 | === added directory 'lib-mvhub/t/Structure' |
1649 | === added file 'lib-mvhub/t/Structure/display_category_chooser.t' |
1650 | --- lib-mvhub/t/Structure/display_category_chooser.t 1970-01-01 00:00:00 +0000 |
1651 | +++ lib-mvhub/t/Structure/display_category_chooser.t 2011-09-11 23:59:29 +0000 |
1652 | @@ -0,0 +1,70 @@ |
1653 | +#!/usr/bin/perl |
1654 | + |
1655 | +use strict; |
1656 | +use warnings; |
1657 | + |
1658 | +use CGI; |
1659 | +use Test::More tests => 4; |
1660 | + |
1661 | +my ( @subs, $out, $result, $cgi ); |
1662 | + |
1663 | +@subs = qw ( display_category_chooser ); |
1664 | + |
1665 | +use_ok( 'MVHub::Structure', @subs ); |
1666 | +can_ok( 'MVHub::Structure', 'display_category_chooser' ); |
1667 | + |
1668 | +close(STDOUT); |
1669 | +open( STDOUT, ">", \$out ) or die "Can't open STDOUT: $!"; |
1670 | + |
1671 | +$ENV{MV_CONFIG_FILE} = $ENV{MV_TEST_CONFIG_FILE}; |
1672 | +$ENV{SCRIPT_NAME} = 'structure.pl'; |
1673 | + |
1674 | +$cgi = CGI->new(); |
1675 | +MVHub::Structure::display_category_chooser($cgi); |
1676 | + |
1677 | +#make output one line |
1678 | +$out =~ s/\n//g; |
1679 | + |
1680 | +$result = check_categories_and_headings($out); |
1681 | +ok( $result, |
1682 | + 'found expected strings in category chooser without success parameter' ); |
1683 | +$out = ''; |
1684 | + |
1685 | +$cgi->param( 'success', '1' ); |
1686 | +MVHub::Structure::display_category_chooser($cgi); |
1687 | + |
1688 | +#make output one line |
1689 | +$out =~ s/\n//g; |
1690 | + |
1691 | +$result = check_categories_and_headings($out); |
1692 | +$result = $result && $out =~ /Your changes have been saved\./; |
1693 | +ok( $result, |
1694 | + 'found expected strings in category chooser with success parameter' ); |
1695 | + |
1696 | +sub check_categories_and_headings { |
1697 | + |
1698 | + my $out = shift; |
1699 | + |
1700 | + #categories |
1701 | + my $result = $out =~ /category_id=1001\">Cultural Heritage/; |
1702 | + $result = $result && $out =~ /category_id=1002\">Music/; |
1703 | + $result = $result && $out =~ /category_id=1003\">Arts \/ Entertainment/; |
1704 | + $result |
1705 | + = $result && $out =~ /category_id=1004\">Theater \/ Performance Art/; |
1706 | + $result = $result && $out =~ /category_id=1005\">Museum/; |
1707 | + $result = $result && $out =~ /category_id=1006\">Arts, Youth/; |
1708 | + $result = $result && $out =~ /category_id=1007\">Culture/; |
1709 | + $result = $result && $out =~ /category_id=1008\">Hotlines, City Services/; |
1710 | + $result = $result && $out =~ /category_id=1009\">Waste Management/; |
1711 | + $result = $result && $out =~ /category_id=1010\">Code Enforcement/; |
1712 | + $result = $result && $out !~ /Dance/; #Nonexist category |
1713 | + |
1714 | + #headings |
1715 | + $result = $result && $out =~ /<h2>Arts\/Culture\/Entertainment<\/h2>/; |
1716 | + $result = $result && $out =~ /<h2>City\/Town Services<\/h2>/; |
1717 | + $result |
1718 | + = $result && $out !~ /<h2>Community\/Civi<\/h2>/; #Nonexist heading |
1719 | + |
1720 | + return $result; |
1721 | + |
1722 | +} |
1723 | |
1724 | === added file 'lib-mvhub/t/Structure/display_structure_menu.t' |
1725 | --- lib-mvhub/t/Structure/display_structure_menu.t 1970-01-01 00:00:00 +0000 |
1726 | +++ lib-mvhub/t/Structure/display_structure_menu.t 2011-09-11 23:59:29 +0000 |
1727 | @@ -0,0 +1,60 @@ |
1728 | +#!/usr/bin/perl |
1729 | + |
1730 | +use strict; |
1731 | +use warnings; |
1732 | + |
1733 | +use CGI; |
1734 | +use Test::More tests => 4; |
1735 | + |
1736 | +my ( @subs, $out, $cgi, $result ); |
1737 | + |
1738 | +@subs = qw ( display_structure_menu ); |
1739 | + |
1740 | +use_ok( 'MVHub::Structure', @subs ); |
1741 | +can_ok( 'MVHub::Structure', 'display_structure_menu' ); |
1742 | + |
1743 | +close(STDOUT); |
1744 | +open( STDOUT, ">", \$out ) or die "Can't open STDOUT: $!"; |
1745 | + |
1746 | +$cgi = CGI->new(); |
1747 | +MVHub::Structure::display_structure_menu($cgi); |
1748 | + |
1749 | +#make output one line |
1750 | +$out =~ s/\n//g; |
1751 | + |
1752 | +$result = check_links_and_titles($out); |
1753 | +ok( $result, 'found expected titles and links without success parameter' ); |
1754 | +$out = ''; |
1755 | + |
1756 | +$cgi->param( 'success', '1' ); |
1757 | +MVHub::Structure::display_structure_menu($cgi); |
1758 | + |
1759 | +#make output one line |
1760 | +$out =~ s/\n//g; |
1761 | + |
1762 | +$result = check_links_and_titles($out); |
1763 | +$result = $result and $out =~ /Your changes have been saved\./; |
1764 | +ok( $result, 'found expected titles and links with success parameter' ); |
1765 | + |
1766 | +sub check_links_and_titles { |
1767 | + |
1768 | + my $out = shift; |
1769 | + |
1770 | + my $result = $out =~ /start structure_menu\.tmpl/; |
1771 | + $result = $result and $out =~ /Add\/Edit Synonyms/; |
1772 | + $result = $result and $out =~ /\/all\/css\/admin\.css/; |
1773 | + $result = $result and $out =~ /Configure the Directory\'s Structure/; |
1774 | + $result = $result and $out =~ /\/html\/admin\/help\/.shtml#search_config/; |
1775 | + $result = $result |
1776 | + and $out =~ /How to Configure the Program Category Search Engine/; |
1777 | + $result = $result |
1778 | + and $out |
1779 | + =~ /\/cgi-bin\/mvhub\/admin\/structure\.pl\?mode=category_chooser/; |
1780 | + $result = $result and $out =~ /Categories/; |
1781 | + $result = $result |
1782 | + and $out |
1783 | + =~ /\/cgi-bin\/mvhub\/admin\/structure\.pl\?mode=edit_synonyms/; |
1784 | + $result = $result and $out =~ /Headings/; |
1785 | + |
1786 | + return $result; |
1787 | +} |
1788 | |
1789 | === added file 'lib-mvhub/t/Structure/fetch_existing_category_and_dependent_data_from_db.t' |
1790 | --- lib-mvhub/t/Structure/fetch_existing_category_and_dependent_data_from_db.t 1970-01-01 00:00:00 +0000 |
1791 | +++ lib-mvhub/t/Structure/fetch_existing_category_and_dependent_data_from_db.t 2011-09-11 23:59:29 +0000 |
1792 | @@ -0,0 +1,95 @@ |
1793 | +#!/usr/bin/perl |
1794 | + |
1795 | +use strict; |
1796 | +use warnings; |
1797 | + |
1798 | +use Test::Deep; |
1799 | +use Test::More tests => 6; |
1800 | + |
1801 | +my @subs = qw( fetch_existing_category_and_dependent_data_from_db ); |
1802 | + |
1803 | +use_ok( 'MVHub::Structure', @subs ); |
1804 | +can_ok( 'MVHub::Structure', |
1805 | + 'fetch_existing_category_and_dependent_data_from_db' ); |
1806 | + |
1807 | +$ENV{MV_CONFIG_FILE} = $ENV{MV_TEST_CONFIG_FILE}; |
1808 | + |
1809 | +my $category_id = 1001; |
1810 | +my $data |
1811 | + = MVHub::Structure::fetch_existing_category_and_dependent_data_from_db( |
1812 | + $category_id); |
1813 | + |
1814 | +my $category_name = 'Cultural Heritage'; |
1815 | +my $aliases = join( "\n", (qw(History)) ); |
1816 | +my $headings = [qw(Arts/Culture/Entertainment)]; |
1817 | +my $programs = [qw(1001 1002 1003 1004 1005)]; |
1818 | + |
1819 | +my $real_data = { |
1820 | + category_name => $category_name, |
1821 | + aliases => $aliases, |
1822 | + headings => $headings, |
1823 | + programs => $programs |
1824 | +}; |
1825 | + |
1826 | +cmp_deeply( $data, $real_data, |
1827 | + 'category and dependent data(with aliases and programs) hashes are same' |
1828 | +); |
1829 | + |
1830 | +$category_id = 1010; |
1831 | +$data = MVHub::Structure::fetch_existing_category_and_dependent_data_from_db( |
1832 | + $category_id); |
1833 | + |
1834 | +$category_name = 'Code Enforcement'; |
1835 | +$aliases = join( "\n", ('Code Violations') ); |
1836 | +$headings = ['City/Town Services']; |
1837 | +$programs = []; |
1838 | + |
1839 | +$real_data = { |
1840 | + category_name => $category_name, |
1841 | + aliases => $aliases, |
1842 | + headings => $headings, |
1843 | + programs => $programs |
1844 | +}; |
1845 | + |
1846 | +cmp_deeply( $data, $real_data, |
1847 | + 'category and dependent data(with only aliases) hashes are same' ); |
1848 | + |
1849 | +$category_id = 1004; |
1850 | +$data = MVHub::Structure::fetch_existing_category_and_dependent_data_from_db( |
1851 | + $category_id); |
1852 | + |
1853 | +$category_name = 'Theater/Performance Art'; |
1854 | +$aliases = join( "\n", () ); |
1855 | +$headings = ['Arts/Culture/Entertainment']; |
1856 | +$programs = [qw(1001 1002)]; |
1857 | + |
1858 | +$real_data = { |
1859 | + category_name => $category_name, |
1860 | + aliases => $aliases, |
1861 | + headings => $headings, |
1862 | + programs => $programs |
1863 | +}; |
1864 | + |
1865 | +cmp_deeply( $data, $real_data, |
1866 | + 'category and dependent data(with only programs) hashes are same' ); |
1867 | + |
1868 | +$category_id = 1008; |
1869 | +$data = MVHub::Structure::fetch_existing_category_and_dependent_data_from_db( |
1870 | + $category_id); |
1871 | + |
1872 | +$category_name = 'Hotlines, City Services'; |
1873 | +$aliases = join( "\n", () ); |
1874 | +$headings = ['City/Town Services']; |
1875 | +$programs = []; |
1876 | + |
1877 | +$real_data = { |
1878 | + category_name => $category_name, |
1879 | + aliases => $aliases, |
1880 | + headings => $headings, |
1881 | + programs => $programs |
1882 | +}; |
1883 | + |
1884 | +cmp_deeply( $data, $real_data, |
1885 | + 'category and dependent data(without aliases and programs) hashes are same' |
1886 | +); |
1887 | + |
1888 | |
1889 | === added file 'lib-mvhub/t/Structure/get_all_headings.t' |
1890 | --- lib-mvhub/t/Structure/get_all_headings.t 1970-01-01 00:00:00 +0000 |
1891 | +++ lib-mvhub/t/Structure/get_all_headings.t 2011-09-11 23:59:29 +0000 |
1892 | @@ -0,0 +1,19 @@ |
1893 | +#!/usr/bin/perl |
1894 | + |
1895 | +use strict; |
1896 | +use warnings; |
1897 | + |
1898 | +use Test::Deep; |
1899 | +use Test::More tests => 3; |
1900 | + |
1901 | +my @subs = qw( get_all_headings ); |
1902 | + |
1903 | +use_ok( 'MVHub::Structure', @subs ); |
1904 | +can_ok( 'MVHub::Structure', 'get_all_headings' ); |
1905 | + |
1906 | +$ENV{MV_CONFIG_FILE} = $ENV{MV_TEST_CONFIG_FILE}; |
1907 | + |
1908 | +my @true_heading = ( 'Arts/Culture/Entertainment', 'City/Town Services' ); |
1909 | +my $heading = MVHub::Structure::get_all_headings(); |
1910 | + |
1911 | +cmp_deeply( $heading, \@true_heading, 'all headings are ok and in order' ); |
1912 | |
1913 | === added file 'lib-mvhub/t/Structure/get_all_programs.t' |
1914 | --- lib-mvhub/t/Structure/get_all_programs.t 1970-01-01 00:00:00 +0000 |
1915 | +++ lib-mvhub/t/Structure/get_all_programs.t 2011-09-11 23:59:29 +0000 |
1916 | @@ -0,0 +1,26 @@ |
1917 | +#!/usr/bin/perl |
1918 | + |
1919 | +use strict; |
1920 | +use warnings; |
1921 | + |
1922 | +use Test::Deep; |
1923 | +use Test::More tests => 3; |
1924 | + |
1925 | +my @subs = qw( get_all_programs ); |
1926 | + |
1927 | +use_ok( 'MVHub::Structure', @subs ); |
1928 | +can_ok( 'MVHub::Structure', 'get_all_programs' ); |
1929 | + |
1930 | +$ENV{MV_CONFIG_FILE} = $ENV{MV_TEST_CONFIG_FILE}; |
1931 | + |
1932 | +my @true_program = ( |
1933 | + { 1001 => 'Test Agency 1: Test Program 1' }, |
1934 | + { 1002 => 'Test Agency 2: Test Program 2' }, |
1935 | + { 1003 => 'Test Agency 3: Test Program 3' }, |
1936 | + { 1004 => 'Test Agency 4: Test Program 4' }, |
1937 | + { 1005 => 'Test Agency 4: Test Program 5' } |
1938 | +); |
1939 | +my $program = MVHub::Structure::get_all_programs(); |
1940 | + |
1941 | +cmp_deeply( $program, \@true_program, 'all programs are ok and in order' ); |
1942 | + |
1943 | |
1944 | === added file 'lib-mvhub/t/Structure/is_category_name_taken.t' |
1945 | --- lib-mvhub/t/Structure/is_category_name_taken.t 1970-01-01 00:00:00 +0000 |
1946 | +++ lib-mvhub/t/Structure/is_category_name_taken.t 2011-09-11 23:59:29 +0000 |
1947 | @@ -0,0 +1,33 @@ |
1948 | +#!/usr/bin/perl |
1949 | + |
1950 | +use strict; |
1951 | +use warnings; |
1952 | + |
1953 | +use Test::More tests => 6; |
1954 | + |
1955 | +my @subs = qw( is_category_name_taken ); |
1956 | + |
1957 | +use_ok( 'MVHub::Structure', @subs ); |
1958 | +can_ok( 'MVHub::Structure', 'is_category_name_taken' ); |
1959 | + |
1960 | +$ENV{MV_CONFIG_FILE} = $ENV{MV_TEST_CONFIG_FILE}; |
1961 | + |
1962 | +my $result |
1963 | + = MVHub::Structure::is_category_name_taken( category_name => 'Culture' ); |
1964 | +is( $result, 1, 'is_category_name_taken_by_only_existing_category_name' ); |
1965 | + |
1966 | +$result = MVHub::Structure::is_category_name_taken( |
1967 | + category_name => 'Non_existing_category_name' ); |
1968 | +is( $result, 0, 'is_category_name_taken_by_only_nonexisting_category_name' ); |
1969 | + |
1970 | +$result = MVHub::Structure::is_category_name_taken( |
1971 | + category_name => 'Culture', |
1972 | + category_id => '1007' |
1973 | +); |
1974 | +is( $result, 0, 'NO, is_category_name_taken_with_category_name_and_id' ); |
1975 | + |
1976 | +$result = MVHub::Structure::is_category_name_taken( |
1977 | + category_name => 'Culture', |
1978 | + category_id => '1008' |
1979 | +); |
1980 | +is( $result, 1, 'YES, is_category_name_taken_with_category_name_and_id' ); |
1981 | |
1982 | === added file 'lib-mvhub/t/Structure/process_category_form.t' |
1983 | --- lib-mvhub/t/Structure/process_category_form.t 1970-01-01 00:00:00 +0000 |
1984 | +++ lib-mvhub/t/Structure/process_category_form.t 2011-09-11 23:59:29 +0000 |
1985 | @@ -0,0 +1,152 @@ |
1986 | +#!/usr/bin/perl |
1987 | + |
1988 | +use strict; |
1989 | +use warnings; |
1990 | + |
1991 | +use CGI; |
1992 | +use Test::Exception; |
1993 | +use Test::More tests => 7; |
1994 | +use Test::Trap; |
1995 | + |
1996 | +my ( $result, $cgi, $test_msg ); |
1997 | + |
1998 | +use_ok( 'MVHub::Structure', qw/ process_category_form / ); |
1999 | +can_ok( 'MVHub::Structure', 'process_category_form' ); |
2000 | + |
2001 | +$ENV{MV_CONFIG_FILE} = $ENV{MV_TEST_CONFIG_FILE}; |
2002 | +$ENV{SCRIPT_NAME} = 'structure.pl'; |
2003 | + |
2004 | +##### |
2005 | +$test_msg |
2006 | + = 'process_category_form() with no inputs returns existing categories'; |
2007 | +##### |
2008 | + |
2009 | +$cgi = CGI->new(); |
2010 | +trap { |
2011 | + MVHub::Structure::process_category_form($cgi); |
2012 | +}; |
2013 | +$result = category_page_has_existing_categories( $trap->stdout() ); |
2014 | +ok( $result, $test_msg ); |
2015 | + |
2016 | +##### |
2017 | +$test_msg |
2018 | + = 'process_category_form() gets category_id parameter returns expected result'; |
2019 | +##### |
2020 | + |
2021 | +$cgi->param( 'category_id', '1001' ); |
2022 | +trap { MVHub::Structure::process_category_form($cgi); }; |
2023 | + |
2024 | +$result = category_page_has_existing_headings_and_programs_aliseses( |
2025 | + $trap->stdout() ); |
2026 | +ok( $result, $test_msg ); |
2027 | + |
2028 | +##### |
2029 | +$test_msg = 'category form dies with non-numeric id:'; |
2030 | +#### |
2031 | + |
2032 | +$cgi->delete('category_id'); |
2033 | +$cgi->param( 'category_id', 'non-numeric id' ); |
2034 | +dies_ok( sub { MVHub::Structure::process_category_form($cgi) }, $test_msg ); |
2035 | + |
2036 | +#### |
2037 | +$test_msg = 'found expected string in successful new category creation'; |
2038 | +#### |
2039 | +TODO: { |
2040 | + local $TODO = "wait to resolve SEQUENCE / nextval() issue in sqlite "; |
2041 | + |
2042 | + $cgi = prepare_cgi_for_successful_creation($cgi); |
2043 | + trap { MVHub::Structure::process_category_form($cgi); }; |
2044 | + |
2045 | + ok( $trap->stdout() =~ /Your changes have been saved\./xms, $test_msg ); |
2046 | +} |
2047 | + |
2048 | +#### |
2049 | +$test_msg = 'found redirect URL after successful edit category'; |
2050 | +#### |
2051 | +$cgi = prepare_cgi_for_successful_edit($cgi); |
2052 | +trap { MVHub::Structure::process_category_form($cgi) }; |
2053 | + |
2054 | +my $expected = q{Location:\s+structure.pl\?mode=structure_menu&success=1}; |
2055 | +ok( $trap->stdout() =~ /$expected/xms, $test_msg ); |
2056 | + |
2057 | +########## |
2058 | + |
2059 | +sub prepare_cgi_for_successful_edit { |
2060 | + |
2061 | + my $cgi = shift; |
2062 | + $cgi->delete_all(); |
2063 | + $cgi->param( 'category_id', '1001' ); |
2064 | + $cgi->param( 'category_name', 'Cultural Heritage' ); |
2065 | + $cgi->param( 'aliases', 'History' ); |
2066 | + $cgi->param( 'headings', 'Arts/Culture/Entertainment' ); |
2067 | + $cgi->param( 'programs', '1001', '1002' ); |
2068 | + $cgi->param( '_submitted_category_editor_form', '2' ); |
2069 | + |
2070 | + return $cgi; |
2071 | +} |
2072 | + |
2073 | +sub prepare_cgi_for_successful_creation { |
2074 | + |
2075 | + my $cgi = shift; |
2076 | + $cgi->delete_all(); |
2077 | + $cgi->param( 'category_name', 'Dance' ); |
2078 | + $cgi->param( 'aliases', 'dance' ); |
2079 | + $cgi->param( 'headings', 'Arts/Culture/Entertainment' ); |
2080 | + $cgi->param( 'programs', '1001', '1002' ); |
2081 | + $cgi->param( '_submitted_category_editor_form', '2' ); |
2082 | + |
2083 | + return $cgi; |
2084 | +} |
2085 | + |
2086 | +sub category_page_has_existing_headings_and_programs_aliseses { |
2087 | + |
2088 | + my $out = shift; |
2089 | + my $match_str; |
2090 | + my $result = $out =~ /Edit a Category/; |
2091 | + |
2092 | + #category |
2093 | + $result |
2094 | + &= $out =~ /category_name\" size.*type.*value=\"Cultural Heritage\"/; |
2095 | + |
2096 | + #alias |
2097 | + $result &= $out =~ /History/; |
2098 | + |
2099 | + #headings |
2100 | + $match_str = q{name="headings".*value="Arts/Culture/Entertainment}; |
2101 | + $result &= $out =~ m|$match_str|xms; |
2102 | + |
2103 | + #programs |
2104 | + $result &= $out |
2105 | + =~ /input checked=\"checked\" name=\"programs\".*value=\"1001\" \/> Test Agency 1: Test Program 1/; |
2106 | + |
2107 | + $result &= $out |
2108 | + =~ /input checked=\"checked\" name=\"programs\".*value=\"1002\" \/> Test Agency 2: Test Program 2/; |
2109 | + |
2110 | + $result &= $out =~ /name=\"programs\".*value=\"1003\"\s*\/>/xms; |
2111 | + |
2112 | + $match_str = q{name="programs".*value="1004"\s*\/>\s*Test\s+Agency\s+4}; |
2113 | + $result &= $out =~ /$match_str/xms; |
2114 | + |
2115 | + return $result; |
2116 | + |
2117 | +} |
2118 | + |
2119 | +sub category_page_has_existing_categories { |
2120 | + |
2121 | + my $out = shift; |
2122 | + my $result = $out =~ /Create a New Category/; |
2123 | + |
2124 | + #headings |
2125 | + $result = $result && $out =~ /Arts\/Culture\/Entertainment/; |
2126 | + $result = $result && $out =~ /City\/Town Services/; |
2127 | + |
2128 | + #programs |
2129 | + $result = $result && $out =~ /Test Program 1/; |
2130 | + $result = $result && $out =~ /Test Program 2/; |
2131 | + $result = $result && $out =~ /Test Program 3/; |
2132 | + $result = $result && $out =~ /Test Program 4/; |
2133 | + $result = $result && $out !~ /Test Porgram 5/; # Nonexist program |
2134 | + |
2135 | + return $result; |
2136 | + |
2137 | +} |
2138 | |
2139 | === added file 'lib-mvhub/t/Structure/process_synonym_form.t' |
2140 | --- lib-mvhub/t/Structure/process_synonym_form.t 1970-01-01 00:00:00 +0000 |
2141 | +++ lib-mvhub/t/Structure/process_synonym_form.t 2011-09-11 23:59:29 +0000 |
2142 | @@ -0,0 +1,130 @@ |
2143 | +#!/usr/bin/perl |
2144 | + |
2145 | +use strict; |
2146 | +use warnings; |
2147 | + |
2148 | +use CGI; |
2149 | +use Test::More tests => 7; |
2150 | + |
2151 | +my ( @subs, $out, $cgi, $result, @synonyms, $new_synonym, $success_message ); |
2152 | + |
2153 | +@subs = qw ( process_synonym_form ); |
2154 | + |
2155 | +use_ok( 'MVHub::Structure', @subs ); |
2156 | +can_ok( 'MVHub::Structure', 'process_synonym_form' ); |
2157 | + |
2158 | +close(STDOUT); |
2159 | +open( STDOUT, ">", \$out ) or die "Can't open STDOUT: $!"; |
2160 | + |
2161 | +$ENV{MV_CONFIG_FILE} = $ENV{MV_TEST_CONFIG_FILE}; |
2162 | +$ENV{SCRIPT_NAME} = 'structure.pl'; |
2163 | + |
2164 | +@synonyms = ( |
2165 | + 'ADD ADHD HADD', |
2166 | + 'alcohol drinking drunk', |
2167 | + 'assist help', |
2168 | + 'cessation quit', |
2169 | + 'child children kid youth', |
2170 | + 'class lesson', |
2171 | + 'computer internet technology', |
2172 | + 'counseling' |
2173 | +); |
2174 | +$new_synonym = 'search bing google'; |
2175 | +$success_message = qr /Your changes have been saved/; |
2176 | +$cgi = CGI->new(); |
2177 | + |
2178 | +MVHub::Structure::process_synonym_form($cgi); |
2179 | + |
2180 | +#make output one line |
2181 | +$out =~ s/\n//g; |
2182 | +$result = check_synonyms( $out, @synonyms ); |
2183 | +$result = $result && $out !~ qr/$new_synonym/; |
2184 | + |
2185 | +ok( $result, 'found expected synonyms before any processing' ); |
2186 | + |
2187 | +TODO: { |
2188 | + |
2189 | + local $TODO = 'Remove TODO block after sqlite sequence problem is solved'; |
2190 | + |
2191 | + $cgi = prepare_cgi( $cgi, @synonyms, $new_synonym ); |
2192 | + |
2193 | + eval { |
2194 | + MVHub::Structure::process_synonym_form($cgi); |
2195 | + |
2196 | + $out =~ s/\n//g; |
2197 | + $result = $out =~ $success_message; |
2198 | + }; |
2199 | + $TODO = 'fails because sequence query is used and not supported by sqlite' |
2200 | + if $@; |
2201 | + $result = 0 if $@; |
2202 | + |
2203 | + ok( $result, 'submit synonyms with new synonym and see success message' ); |
2204 | + $out = ''; |
2205 | + |
2206 | + $cgi->delete_all(); |
2207 | + |
2208 | + eval { |
2209 | + MVHub::Structure::process_synonym_form($cgi); |
2210 | + |
2211 | + $out =~ s/\n//g; |
2212 | + $result = check_synonyms( $out, @synonyms ); |
2213 | + $result = $result && $out =~ qr /$new_synonym/; |
2214 | + }; |
2215 | + |
2216 | + $TODO = 'fails because addition could not be done due to sequences'; |
2217 | + |
2218 | + ok( $result, 'found expected synonyms after addition' ); |
2219 | + $out = ''; |
2220 | + |
2221 | + $cgi = prepare_cgi( $cgi, @synonyms ); |
2222 | + |
2223 | + eval { |
2224 | + MVHub::Structure::process_synonym_form($cgi); |
2225 | + |
2226 | + $out =~ s/\n//g; |
2227 | + $result = $out =~ $success_message; |
2228 | + }; |
2229 | + $TODO = 'fails because sequence query is used and not supported by sqlite' |
2230 | + if $@; |
2231 | + |
2232 | + ok( $result, |
2233 | + 'submit synonyms without new synonym and see success message' ); |
2234 | + $out = ''; |
2235 | +} |
2236 | + |
2237 | +##### |
2238 | +$cgi->delete_all(); |
2239 | +MVHub::Structure::process_synonym_form($cgi); |
2240 | + |
2241 | +$out =~ s/\n//g; |
2242 | +$result = check_synonyms( $out, @synonyms ); |
2243 | +$result = $result && $out !~ qr/$new_synonym/; |
2244 | + |
2245 | +ok( $result, 'found expected synonyms after deletion' ); |
2246 | + |
2247 | +sub prepare_cgi { |
2248 | + |
2249 | + my $cgi = shift; |
2250 | + my $new_synonym = shift; |
2251 | + $cgi->delete_all(); |
2252 | + my $synonyms = join( "\n", @synonyms ); |
2253 | + if ($new_synonym) { |
2254 | + $synonyms .= "\n" . $new_synonym; |
2255 | + } |
2256 | + $cgi->param( 'synonyms', $synonyms ); |
2257 | + return $cgi; |
2258 | + |
2259 | +} |
2260 | + |
2261 | +sub check_synonyms { |
2262 | + |
2263 | + my $out = shift; |
2264 | + my @synonyms = shift; |
2265 | + |
2266 | + my $result = 1; |
2267 | + foreach my $synonym (@synonyms) { |
2268 | + $result = $result && $out =~ qr/$synonym/; |
2269 | + } |
2270 | + |
2271 | + return $result; |
2272 | +} |
2273 | |
2274 | === added directory 'lib-mvhub/t/Synonyms' |
2275 | === added file 'lib-mvhub/t/Synonyms/fetch_synonyms_from_db.t' |
2276 | --- lib-mvhub/t/Synonyms/fetch_synonyms_from_db.t 1970-01-01 00:00:00 +0000 |
2277 | +++ lib-mvhub/t/Synonyms/fetch_synonyms_from_db.t 2011-09-11 23:59:29 +0000 |
2278 | @@ -0,0 +1,29 @@ |
2279 | +#!/usr/bin/perl |
2280 | + |
2281 | +use strict; |
2282 | +use warnings; |
2283 | +use Test::More tests => 3; |
2284 | +use Test::Deep; |
2285 | + |
2286 | +use MVHub::Synonyms; |
2287 | + |
2288 | +my @subs = qw( fetch_synonyms_from_db ); |
2289 | + |
2290 | +use_ok( 'MVHub::Synonyms', @subs ); |
2291 | +can_ok( __PACKAGE__, 'fetch_synonyms_from_db' ); |
2292 | + |
2293 | +$ENV{MV_CONFIG_FILE} = $ENV{MV_TEST_CONFIG_FILE}; |
2294 | + |
2295 | +my @real_synonyms = ( |
2296 | + 'ADD ADHD HADD', |
2297 | + 'alcohol drinking drunk', |
2298 | + 'assist help', |
2299 | + 'cessation quit', |
2300 | + 'child children kid youth', |
2301 | + 'class lesson', |
2302 | + 'computer internet technology', |
2303 | + 'counseling', |
2304 | +); |
2305 | +my @synonyms = MVHub::Synonyms::fetch_synonyms_from_db(); |
2306 | + |
2307 | +cmp_deeply( \@synonyms, \@real_synonyms, 'synonym arrays are same' ); |
2308 | |
2309 | === modified file 'lib-mvhub/t/Utils/clean_cgi_params.t' |
2310 | --- lib-mvhub/t/Utils/clean_cgi_params.t 2010-09-27 13:28:16 +0000 |
2311 | +++ lib-mvhub/t/Utils/clean_cgi_params.t 2011-09-11 23:59:29 +0000 |
2312 | @@ -1,8 +1,10 @@ |
2313 | #!/usr/bin/perl -w |
2314 | |
2315 | use strict; |
2316 | + |
2317 | +use CGI; |
2318 | use Test::More tests => 7; |
2319 | -use CGI; |
2320 | + |
2321 | use MVHub::Utils; |
2322 | |
2323 | my $q = CGI->new(); |
2324 | @@ -64,7 +66,7 @@ |
2325 | |
2326 | #### |
2327 | $test_name |
2328 | - = "multitple mixed parameters with same name are selectively cleaned"; |
2329 | + = "multiple mixed parameters with same name are selectively cleaned"; |
2330 | #### |
2331 | $q->param( |
2332 | mixed_multi => "clean", |
2333 | |
2334 | === modified file 'lib-mvhub/t/lib/TestData.pm' |
2335 | --- lib-mvhub/t/lib/TestData.pm 2010-10-16 00:29:43 +0000 |
2336 | +++ lib-mvhub/t/lib/TestData.pm 2011-09-11 23:59:29 +0000 |
2337 | @@ -9,7 +9,16 @@ |
2338 | use Exporter (); |
2339 | our (@EXPORT_OK); |
2340 | |
2341 | - @EXPORT_OK = qw(@agency @program notifications_href); |
2342 | + @EXPORT_OK = qw(@agency |
2343 | + @program |
2344 | + notifications_href |
2345 | + @category |
2346 | + @program_category |
2347 | + @alias |
2348 | + @synonym_stem |
2349 | + @heading |
2350 | + @heading_category); |
2351 | + |
2352 | } |
2353 | our @EXPORT_OK; |
2354 | |
2355 | @@ -17,7 +26,8 @@ |
2356 | my $dev_user = $test_data_cfg->param('NOTIFICATION.dev_email'); |
2357 | |
2358 | our @agency = ( |
2359 | - { agency_id => '1001', |
2360 | + { |
2361 | + agency_id => '1001', |
2362 | agency_name => 'Test Agency 1', |
2363 | record_name => 'Test Agency 1 (Main Agency Record)', |
2364 | contact_first_name => 'Dan', |
2365 | @@ -27,7 +37,8 @@ |
2366 | last_updated => '2009-02-15', |
2367 | reminders_sent => '0', |
2368 | }, |
2369 | - { agency_id => '1002', |
2370 | + { |
2371 | + agency_id => '1002', |
2372 | agency_name => 'Test Agency 2', |
2373 | record_name => 'Test Agency 2 (Main Agency Record)', |
2374 | contact_first_name => 'Jane', |
2375 | @@ -37,7 +48,8 @@ |
2376 | last_updated => '2008-12-02', |
2377 | reminders_sent => '1', |
2378 | }, |
2379 | - { agency_id => '1003', |
2380 | + { |
2381 | + agency_id => '1003', |
2382 | agency_name => 'Test Agency 3', |
2383 | record_name => 'Test Agency 3 (Main Agency Record)', |
2384 | contact_first_name => 'Jack', |
2385 | @@ -47,7 +59,8 @@ |
2386 | last_updated => '2008-06-05', |
2387 | reminders_sent => '2', |
2388 | }, |
2389 | - { agency_id => '1004', |
2390 | + { |
2391 | + agency_id => '1004', |
2392 | agency_name => 'Test Agency 4', |
2393 | record_name => 'Test Agency 4 (Main Agency Record)', |
2394 | contact_first_name => 'Sue', |
2395 | @@ -57,7 +70,8 @@ |
2396 | last_updated => '2007-08-20', |
2397 | reminders_sent => '1', |
2398 | }, |
2399 | - { agency_id => '1005', |
2400 | + { |
2401 | + agency_id => '1005', |
2402 | agency_name => 'Test Agency 5', |
2403 | record_name => 'Test Agency 5 (Main Agency Record)', |
2404 | contact_first_name => 'Bob', |
2405 | @@ -70,8 +84,9 @@ |
2406 | ); |
2407 | |
2408 | our @program = ( |
2409 | - { agency_id => '1001', |
2410 | - agency_name => 'Test Agency 1', |
2411 | + { |
2412 | + agency_id => '1001', |
2413 | + program_id => '1001', |
2414 | record_name => 'Test Program 1', |
2415 | contact_first_name => 'Joe', |
2416 | contact_last_name => 'Schmoe', |
2417 | @@ -80,8 +95,9 @@ |
2418 | last_updated => '2009-02-15', |
2419 | reminders_sent => '0', |
2420 | }, |
2421 | - { agency_id => '1002', |
2422 | - agency_name => 'Test Agency 2', |
2423 | + { |
2424 | + agency_id => '1002', |
2425 | + program_id => '1002', |
2426 | record_name => 'Test Program 2', |
2427 | contact_first_name => 'Jane', |
2428 | contact_last_name => 'Lane', |
2429 | @@ -90,8 +106,9 @@ |
2430 | last_updated => '2008-12-02', |
2431 | reminders_sent => '0', |
2432 | }, |
2433 | - { agency_id => '1003', |
2434 | - agency_name => 'Test Agency 3', |
2435 | + { |
2436 | + agency_id => '1003', |
2437 | + program_id => '1003', |
2438 | record_name => 'Test Program 3', |
2439 | contact_first_name => 'Jack', |
2440 | contact_last_name => 'Black', |
2441 | @@ -100,8 +117,9 @@ |
2442 | last_updated => '2008-12-02', |
2443 | reminders_sent => '2', |
2444 | }, |
2445 | - { agency_id => '1004', |
2446 | - agency_name => 'Test Agency 4', |
2447 | + { |
2448 | + agency_id => '1004', |
2449 | + program_id => '1004', |
2450 | record_name => 'Test Program 4', |
2451 | contact_first_name => 'Sue', |
2452 | contact_last_name => 'Blue', |
2453 | @@ -110,6 +128,17 @@ |
2454 | last_updated => '2008-12-02', |
2455 | reminders_sent => '3', |
2456 | }, |
2457 | + { |
2458 | + agency_id => '1004', |
2459 | + program_id => '1005', |
2460 | + record_name => 'Test Program 5', |
2461 | + contact_first_name => 'Lou', |
2462 | + contact_last_name => 'Blue', |
2463 | + contact_email => 'lou_blue@example.com', |
2464 | + email => 'lou_public@example.com', |
2465 | + last_updated => '2008-12-02', |
2466 | + reminders_sent => '2', |
2467 | + }, |
2468 | ); |
2469 | |
2470 | our $notifications_href = { |
2471 | @@ -119,7 +148,7 @@ |
2472 | 'contact_last_name' => 'Schmoe', |
2473 | 'reminders_sent' => 0, |
2474 | 'expired_record_list' => |
2475 | - [ 'Test Program 1', 'Test Agency 1 (Main Agency Record)' ], |
2476 | + [ 'Test Program 1', 'Test Agency 1 (Main Agency Record)' ], |
2477 | 'agency_contact_email' => 'joe_agency@example.com', |
2478 | 'contact_email' => $dev_user, |
2479 | 'public_email' => 'joe_public@example.com', |
2480 | @@ -132,7 +161,7 @@ |
2481 | 'contact_last_name' => 'Lane', |
2482 | 'reminders_sent' => 1, |
2483 | 'expired_record_list' => |
2484 | - [ 'Test Program 2', 'Test Agency 2 (Main Agency Record)' ], |
2485 | + [ 'Test Program 2', 'Test Agency 2 (Main Agency Record)' ], |
2486 | 'agency_contact_email' => 'jane_agency@example.com', |
2487 | 'contact_email' => $dev_user, |
2488 | 'public_email' => 'jane_public@example.com', |
2489 | @@ -145,7 +174,7 @@ |
2490 | 'contact_last_name' => 'Black', |
2491 | 'reminders_sent' => 2, |
2492 | 'expired_record_list' => |
2493 | - [ 'Test Program 3', 'Test Agency 3 (Main Agency Record)' ], |
2494 | + [ 'Test Program 3', 'Test Agency 3 (Main Agency Record)' ], |
2495 | 'agency_contact_email' => 'jack_agency@example.com', |
2496 | 'contact_email' => $dev_user, |
2497 | 'public_email' => 'jack_public@example.com', |
2498 | @@ -158,7 +187,7 @@ |
2499 | 'contact_last_name' => 'Blue', |
2500 | 'reminders_sent' => 3, |
2501 | 'expired_record_list' => |
2502 | - [ 'Test Program 4', 'Test Agency 4 (Main Agency Record)' ], |
2503 | + [ 'Test Program 4', 'Test Program 5', 'Test Agency 4 (Main Agency Record)' ], |
2504 | 'agency_contact_email' => 'sue_agency@example.com', |
2505 | 'contact_email' => $dev_user, |
2506 | 'public_email' => 'sue_public@example.com', |
2507 | @@ -180,5 +209,286 @@ |
2508 | }, |
2509 | }; |
2510 | |
2511 | +our @category = ( |
2512 | + { |
2513 | + category_id => '1001', |
2514 | + category_name => 'Cultural Heritage', |
2515 | + stems_name => 'cultur heritag', |
2516 | + }, |
2517 | + { |
2518 | + category_id => '1002', |
2519 | + category_name => 'Music', |
2520 | + stems_name => 'music', |
2521 | + }, |
2522 | + { |
2523 | + category_id => '1003', |
2524 | + category_name => 'Arts/Entertainment', |
2525 | + stems_name => 'entertain art', |
2526 | + }, |
2527 | + { |
2528 | + category_id => '1004', |
2529 | + category_name => 'Theater/Performance Art', |
2530 | + stems_name => 'art perform theater', |
2531 | + }, |
2532 | + { |
2533 | + category_id => '1005', |
2534 | + category_name => 'Museum', |
2535 | + stems_name => 'museum', |
2536 | + }, |
2537 | + { |
2538 | + category_id => '1006', |
2539 | + category_name => 'Arts, Youth', |
2540 | + stems_name => 'youth art', |
2541 | + }, |
2542 | + { |
2543 | + category_id => '1007', |
2544 | + category_name => 'Culture', |
2545 | + stems_name => 'cultur', |
2546 | + }, |
2547 | + { |
2548 | + category_id => '1008', |
2549 | + category_name => 'Hotlines, City Services', |
2550 | + stems_name => 'servic hotlin citi', |
2551 | + }, |
2552 | + { |
2553 | + category_id => '1009', |
2554 | + category_name => 'Waste Management', |
2555 | + stems_name => 'wast manag', |
2556 | + }, |
2557 | + { |
2558 | + category_id => '1010', |
2559 | + category_name => 'Code Enforcement', |
2560 | + stems_name => 'enforc code', |
2561 | + }, |
2562 | + |
2563 | +); |
2564 | +our @program_category = ( |
2565 | + { |
2566 | + category_id => '1001', |
2567 | + program_id => '1001', |
2568 | + }, |
2569 | + { |
2570 | + category_id => '1002', |
2571 | + program_id => '1001', |
2572 | + }, |
2573 | + { |
2574 | + category_id => '1003', |
2575 | + program_id => '1001', |
2576 | + }, |
2577 | + { |
2578 | + category_id => '1004', |
2579 | + program_id => '1001', |
2580 | + }, |
2581 | + { |
2582 | + category_id => '1005', |
2583 | + program_id => '1001', |
2584 | + }, |
2585 | + { |
2586 | + category_id => '1001', |
2587 | + program_id => '1002', |
2588 | + }, |
2589 | + { |
2590 | + category_id => '1002', |
2591 | + program_id => '1002', |
2592 | + }, |
2593 | + { |
2594 | + category_id => '1003', |
2595 | + program_id => '1002', |
2596 | + }, |
2597 | + { |
2598 | + category_id => '1004', |
2599 | + program_id => '1002', |
2600 | + }, |
2601 | + { |
2602 | + category_id => '1001', |
2603 | + program_id => '1003', |
2604 | + }, |
2605 | + { |
2606 | + category_id => '1002', |
2607 | + program_id => '1003', |
2608 | + }, |
2609 | + { |
2610 | + category_id => '1003', |
2611 | + program_id => '1003', |
2612 | + }, |
2613 | + { |
2614 | + category_id => '1001', |
2615 | + program_id => '1004', |
2616 | + }, |
2617 | + { |
2618 | + category_id => '1002', |
2619 | + program_id => '1004', |
2620 | + }, |
2621 | + { |
2622 | + category_id => '1001', |
2623 | + program_id => '1005', |
2624 | + }, |
2625 | +); |
2626 | + |
2627 | +our @alias = ( |
2628 | + { |
2629 | + category_id => '1001', |
2630 | + alias_name => 'History', |
2631 | + stems_name => 'histori', |
2632 | + }, |
2633 | + { |
2634 | + category_id => '1010', |
2635 | + alias_name => 'Code Violations', |
2636 | + stems_name => 'code violat', |
2637 | + }, |
2638 | +); |
2639 | + |
2640 | +our @synonym_stem = ( |
2641 | + { |
2642 | + synonym_id => '1001', |
2643 | + word_stem => 'add', |
2644 | + submitted_word => 'ADD', |
2645 | + }, |
2646 | + { |
2647 | + synonym_id => '1001', |
2648 | + word_stem => 'adhd', |
2649 | + submitted_word => 'ADHD', |
2650 | + }, |
2651 | + { |
2652 | + synonym_id => '1001', |
2653 | + word_stem => 'hadd', |
2654 | + submitted_word => 'HADD', |
2655 | + }, |
2656 | + { |
2657 | + synonym_id => '1002', |
2658 | + word_stem => 'alcohol', |
2659 | + submitted_word => 'alcohol', |
2660 | + }, |
2661 | + { |
2662 | + synonym_id => '1002', |
2663 | + word_stem => 'drink', |
2664 | + submitted_word => 'drinking', |
2665 | + }, |
2666 | + { |
2667 | + synonym_id => '1002', |
2668 | + word_stem => 'drunk', |
2669 | + submitted_word => 'drunk', |
2670 | + }, |
2671 | + { |
2672 | + synonym_id => '1003', |
2673 | + word_stem => 'assist', |
2674 | + submitted_word => 'assist', |
2675 | + }, |
2676 | + { |
2677 | + synonym_id => '1003', |
2678 | + word_stem => 'help', |
2679 | + submitted_word => 'help', |
2680 | + }, |
2681 | + { |
2682 | + synonym_id => '1004', |
2683 | + word_stem => 'cessat', |
2684 | + submitted_word => 'cessation', |
2685 | + }, |
2686 | + { |
2687 | + synonym_id => '1004', |
2688 | + word_stem => 'quit', |
2689 | + submitted_word => 'quit', |
2690 | + }, |
2691 | + { |
2692 | + synonym_id => '1005', |
2693 | + word_stem => 'child', |
2694 | + submitted_word => 'child', |
2695 | + }, |
2696 | + { |
2697 | + synonym_id => '1005', |
2698 | + word_stem => 'children', |
2699 | + submitted_word => 'children', |
2700 | + }, |
2701 | + { |
2702 | + synonym_id => '1005', |
2703 | + word_stem => 'kid', |
2704 | + submitted_word => 'kid', |
2705 | + }, |
2706 | + { |
2707 | + synonym_id => '1005', |
2708 | + word_stem => 'youth', |
2709 | + submitted_word => 'youth', |
2710 | + }, |
2711 | + { |
2712 | + synonym_id => '1006', |
2713 | + word_stem => 'class', |
2714 | + submitted_word => 'class', |
2715 | + }, |
2716 | + { |
2717 | + synonym_id => '1006', |
2718 | + word_stem => 'lesson', |
2719 | + submitted_word => 'lesson', |
2720 | + }, |
2721 | + { |
2722 | + synonym_id => '1007', |
2723 | + word_stem => 'comput', |
2724 | + submitted_word => 'computer', |
2725 | + }, |
2726 | + { |
2727 | + synonym_id => '1007', |
2728 | + word_stem => 'technologi', |
2729 | + submitted_word => 'technology', |
2730 | + }, |
2731 | + { |
2732 | + synonym_id => '1007', |
2733 | + word_stem => 'internet', |
2734 | + submitted_word => 'internet', |
2735 | + }, |
2736 | + { |
2737 | + synonym_id => '1008', |
2738 | + word_stem => 'counsel', |
2739 | + submitted_word => 'counseling', |
2740 | + }, |
2741 | +); |
2742 | + |
2743 | +our @heading = ( |
2744 | + { heading_name => 'Arts/Culture/Entertainment', }, |
2745 | + { heading_name => 'City/Town Services', }, |
2746 | +); |
2747 | + |
2748 | +our @heading_category = ( |
2749 | + { |
2750 | + category_id => '1001', |
2751 | + heading_name => 'Arts/Culture/Entertainment', |
2752 | + }, |
2753 | + { |
2754 | + category_id => '1002', |
2755 | + heading_name => 'Arts/Culture/Entertainment', |
2756 | + }, |
2757 | + { |
2758 | + category_id => '1003', |
2759 | + heading_name => 'Arts/Culture/Entertainment', |
2760 | + }, |
2761 | + { |
2762 | + category_id => '1004', |
2763 | + heading_name => 'Arts/Culture/Entertainment', |
2764 | + }, |
2765 | + { |
2766 | + category_id => '1005', |
2767 | + heading_name => 'Arts/Culture/Entertainment', |
2768 | + }, |
2769 | + { |
2770 | + category_id => '1006', |
2771 | + heading_name => 'Arts/Culture/Entertainment', |
2772 | + }, |
2773 | + { |
2774 | + category_id => '1007', |
2775 | + heading_name => 'Arts/Culture/Entertainment', |
2776 | + }, |
2777 | + { |
2778 | + category_id => '1008', |
2779 | + heading_name => 'City/Town Services', |
2780 | + }, |
2781 | + { |
2782 | + category_id => '1009', |
2783 | + heading_name => 'City/Town Services', |
2784 | + }, |
2785 | + { |
2786 | + category_id => '1010', |
2787 | + heading_name => 'City/Town Services', |
2788 | + }, |
2789 | + |
2790 | +); |
2791 | + |
2792 | # all good modules return true 1; |
2793 | 1 |
2794 | |
2795 | === modified file 'lib-mvhub/t/lib/TestHelper.pm' |
2796 | --- lib-mvhub/t/lib/TestHelper.pm 2011-03-31 16:31:33 +0000 |
2797 | +++ lib-mvhub/t/lib/TestHelper.pm 2011-09-11 23:59:29 +0000 |
2798 | @@ -20,6 +20,7 @@ |
2799 | add_test_data |
2800 | create_sqlite_db |
2801 | create_temp_auth |
2802 | + get_admin_username_password(); |
2803 | get_files |
2804 | get_files_from |
2805 | get_host_to_check |
2806 | @@ -33,8 +34,6 @@ |
2807 | submit_forms_ok |
2808 | ); |
2809 | |
2810 | -our ($VERSION) = '$Revision: 1647 $' =~ /([.\d]+)/; |
2811 | - |
2812 | sub add_test_data { |
2813 | my $dbh = shift or croak "missing parameter: \$dbh\n"; |
2814 | my $sql = MVHub::Utils::DB::get_sql_insert_statement( |
2815 | @@ -59,6 +58,57 @@ |
2816 | ); |
2817 | $dbh->do( $sql, undef, @bind_variables ); |
2818 | } |
2819 | + $sql = MVHub::Utils::DB::get_sql_insert_statement( |
2820 | + 'CATEGORY_X_REQUIRED_FIELDS'); |
2821 | + foreach my $test_data (@TestData::category) { |
2822 | + @bind_variables = ( |
2823 | + $test_data->{'category_id'}, |
2824 | + $test_data->{'category_name'}, |
2825 | + $test_data->{'stems_name'} |
2826 | + ); |
2827 | + $dbh->do( $sql, undef, @bind_variables ); |
2828 | + } |
2829 | + $sql = MVHub::Utils::DB::get_sql_insert_statement( |
2830 | + 'PROGRAM_CATEGORY_X_REQUIRED_FIELDS'); |
2831 | + foreach my $test_data (@TestData::program_category) { |
2832 | + @bind_variables |
2833 | + = ( $test_data->{'program_id'}, $test_data->{'category_id'} ); |
2834 | + $dbh->do( $sql, undef, @bind_variables ); |
2835 | + } |
2836 | + $sql = MVHub::Utils::DB::get_sql_insert_statement( |
2837 | + 'ALIAS_X_REQUIRED_FIELDS'); |
2838 | + foreach my $test_data (@TestData::alias) { |
2839 | + @bind_variables = ( |
2840 | + $test_data->{'category_id'}, |
2841 | + $test_data->{'alias_name'}, |
2842 | + $test_data->{'stems_name'} |
2843 | + ); |
2844 | + $dbh->do( $sql, undef, @bind_variables ); |
2845 | + } |
2846 | + $sql = MVHub::Utils::DB::get_sql_insert_statement( |
2847 | + 'SYNONYM_STEM_X_REQUIRED_FIELDS'); |
2848 | + foreach my $test_data (@TestData::synonym_stem) { |
2849 | + @bind_variables = ( |
2850 | + $test_data->{'synonym_id'}, |
2851 | + $test_data->{'word_stem'}, |
2852 | + $test_data->{'submitted_word'} |
2853 | + ); |
2854 | + $dbh->do( $sql, undef, @bind_variables ); |
2855 | + } |
2856 | + $sql = MVHub::Utils::DB::get_sql_insert_statement( |
2857 | + 'HEADING_X_REQUIRED_FIELDS'); |
2858 | + foreach my $test_data (@TestData::heading) { |
2859 | + @bind_variables = ( $test_data->{'heading_name'} ); |
2860 | + $dbh->do( $sql, undef, @bind_variables ); |
2861 | + } |
2862 | + $sql = MVHub::Utils::DB::get_sql_insert_statement( |
2863 | + 'HEADING_CATEGORY_X_REQUIRED_FIELDS'); |
2864 | + foreach my $test_data (@TestData::heading_category) { |
2865 | + @bind_variables |
2866 | + = ( $test_data->{'category_id'}, $test_data->{'heading_name'} ); |
2867 | + $dbh->do( $sql, undef, @bind_variables ); |
2868 | + } |
2869 | + |
2870 | } |
2871 | |
2872 | sub create_sqlite_db { |
2873 | @@ -72,6 +122,7 @@ |
2874 | my $sql = $sql_lib->retr($sql_label); |
2875 | $dbh->do($sql); |
2876 | } |
2877 | + |
2878 | return 1; |
2879 | } |
2880 | |
2881 | @@ -85,6 +136,12 @@ |
2882 | return $auth; |
2883 | } |
2884 | |
2885 | +sub get_admin_username_password { |
2886 | + |
2887 | + return qw/ test test /; |
2888 | + |
2889 | +} |
2890 | + |
2891 | # accept a list of wild card file patterns |
2892 | # return a list (array) of all files in project directory matching |
2893 | # examples: |
Changes getting bigger so I submitted to check whether I am on the right path.