Skip to content

Commit cf472ea

Browse files
committed
WIP: fix up tests and general cleanup.
WIP: fix up tests and general cleanup. WIP: fix up tests and general cleanup.
1 parent 60d43eb commit cf472ea

File tree

17 files changed

+160
-205
lines changed

17 files changed

+160
-205
lines changed

lib/DB/Schema/Result/CourseSetting.pm

+5-8
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,16 @@ __PACKAGE__->add_columns(
4343
is_auto_increment => 1,
4444
},
4545
course_id => {
46-
data_type => 'integer',
47-
size => 16,
48-
is_nullable => 0,
46+
data_type => 'integer',
47+
size => 16,
4948
},
5049
setting_id => {
51-
data_type => 'integer',
52-
size => 16,
53-
is_nullable => 0,
50+
data_type => 'integer',
51+
size => 16,
5452
},
5553
value => {
5654
data_type => 'text',
57-
is_nullable => 0,
58-
default_value => '\'\'',
55+
default_value => '{}',
5956
serializer_class => 'JSON',
6057
serializer_options => { utf8 => 1 }
6158
},

lib/DB/Schema/Result/CourseSettings.pm

-118
This file was deleted.

lib/DB/Schema/Result/GlobalSetting.pm

+7-13
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ C<type>: a string representation of the type of setting (boolean, text, list, ..
3737
3838
=item *
3939
40-
C<options>: a JSON object that stores options if the setting is an list or multilist
40+
C<options>: a JSON array that stores options if the setting is an list or multilist
4141
4242
=item *
4343
@@ -59,24 +59,21 @@ __PACKAGE__->add_columns(
5959
setting_id => {
6060
data_type => 'integer',
6161
size => 16,
62-
is_nullable => 0,
6362
is_auto_increment => 1,
6463
},
6564
setting_name => {
66-
data_type => 'varchar',
67-
size => 256,
68-
is_nullable => 0,
65+
data_type => 'varchar',
66+
size => 256,
6967
},
7068
default_value => {
7169
data_type => 'text',
72-
is_nullable => 0,
73-
default_value => '\'\'',
70+
default_value => '{}',
71+
retrieve_on_insert => 1,
7472
serializer_class => 'JSON',
7573
serializer_options => { utf8 => 1 }
7674
},
7775
description => {
7876
data_type => 'text',
79-
is_nullable => 0,
8077
default_value => '',
8178
},
8279
doc => {
@@ -85,20 +82,19 @@ __PACKAGE__->add_columns(
8582
},
8683
type => {
8784
data_type => 'varchar',
88-
size => 16,
89-
is_nullable => 0,
85+
size => 64,
9086
default_value => '',
9187
},
9288
options => {
9389
data_type => 'text',
9490
is_nullable => 1,
91+
retrieve_on_insert => 1,
9592
serializer_class => 'JSON',
9693
serializer_options => { utf8 => 1 }
9794
},
9895
category => {
9996
data_type => 'varchar',
10097
size => 64,
101-
is_nullable => 0,
10298
default_value => ''
10399
},
104100
subcategory => {
@@ -112,6 +108,4 @@ __PACKAGE__->set_primary_key('setting_id');
112108

113109
__PACKAGE__->has_many(course_settings => 'DB::Schema::Result::CourseSetting', 'setting_id');
114110

115-
# __PACKAGE__->belongs_to(course => 'DB::Schema::Result::Course', 'course_id');
116-
117111
1;

lib/DB/Schema/ResultSet/Course.pm

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ use base 'DBIx::Class::ResultSet';
1010
use Clone qw/clone/;
1111
use DB::Utils qw/getCourseInfo getUserInfo getSettingInfo/;
1212

13-
use Exception::Class qw(
13+
use Exception::Class qw/
1414
DB::Exception::CourseNotFound
1515
DB::Exception::CourseExists
1616
DB::Exception::SettingNotFound
17-
);
17+
/;
1818

1919
use WeBWorK3::Utils::Settings qw/ mergeCourseSettings isValidSetting/;
2020

lib/DB/Utils.pm

+34-6
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ use feature 'signatures';
66
no warnings qw/experimental::signatures/;
77

88
require Exporter;
9-
use base qw(Exporter);
9+
use base qw/Exporter/;
1010
our @EXPORT_OK = qw/getCourseInfo getUserInfo getSetInfo updateAllFields updatePermissions
1111
getPoolInfo getProblemInfo getPoolProblemInfo getSettingInfo removeLoginParams
12-
convertTimeDuration/;
12+
convertTimeDuration humanReadableTimeDuration/;
1313

1414
use Clone qw/clone/;
1515
use Scalar::Util qw/reftype/;
@@ -205,15 +205,43 @@ sub convertTimeDuration ($time_duration) {
205205
if ($time_duration =~ /^(\d+)\s(sec)s?$/) {
206206
return $1;
207207
} elsif ($time_duration =~ /^(\d+)\s(min(ute)?)s?$/) {
208-
return $1*60;
208+
return $1 * 60;
209209
} elsif ($time_duration =~ /^(\d+)\s(h(ou)?r)s?$/) {
210-
return $1*60*60;
210+
return $1 * 60 * 60;
211211
} elsif ($time_duration =~ /^(\d+)\s(day)s?$/) {
212-
return $1*60*60*24;
212+
return $1 * 60 * 60 * 24;
213213
} elsif ($time_duration =~ /^(\d+)\s(week)s?$/) {
214-
return $1*60*60*24*7;
214+
return $1 * 60 * 60 * 24 * 7;
215+
} else {
216+
return 0;
215217
}
216218
}
217219

220+
=pod
221+
=head2
222+
223+
This coverts a number of seconds to a human-readable format
224+
225+
=cut
226+
227+
sub humanReadableTimeDuration ($td) {
228+
my $times = {
229+
week => int($td / 604800),
230+
day => int($td % 604800 / 86400),
231+
hour => int($td % 86400 / 3600),
232+
min => int($td % 3600 / 60),
233+
sec => $td % 60
234+
};
235+
236+
my $time_duration = '';
237+
# Order is important so the keys are defined.
238+
for (qw/week day hour min sec/) {
239+
my $val = $times->{$_};
240+
$time_duration .= ($time_duration ne '' && $val ? ', ' : '')
241+
# pluralize for more than 1.
242+
. ($val > 0 ? "$val $_" . ($val == 1 ? '' : 's') : '');
243+
}
244+
return $time_duration;
245+
}
218246

219247
1;

lib/WeBWorK3.pm

+2-2
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ sub problemRoutes ($app, $course_routes) {
216216
return;
217217
}
218218

219-
sub settingsRoutes ($self, $course_routes) {
220-
my $global_settings = $self->routes->any('/webwork3/api/global-settings')->requires(authenticated => 1);
219+
sub settingsRoutes ($app, $course_routes) {
220+
my $global_settings = $app->routes->any('/webwork3/api/global-settings')->requires(authenticated => 1);
221221
$global_settings->get('/')->to('Settings#getGlobalSettings');
222222
$global_settings->get('/:setting_id')->to('Settings#getGlobalSetting');
223223
$global_settings->post('/check-timezone')->to('Settings#checkTimeZone');

lib/WeBWorK3/Controller/Settings.pm

+3
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ sub deleteCourseSetting ($c) {
6565
return;
6666
}
6767

68+
# This is useful for checking if the string passed in is a valid timezone, instead of
69+
# having the UI download all possible timezones (bloated).
70+
6871
sub checkTimeZone ($c) {
6972
try {
7073
DateTime::TimeZone->new(name => $c->req->json->{timezone});

lib/WeBWorK3/Utils/Settings.pm

+11-12
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ no warnings qw/experimental::signatures/;
88
use YAML::XS qw/LoadFile/;
99

1010
require Exporter;
11-
use base qw(Exporter);
11+
use base qw/Exporter/;
1212
our @EXPORT_OK = qw/isValidSetting mergeCourseSettings isInteger isTimeString isTimeDuration isDecimal/;
1313

14-
use Exception::Class qw(
14+
use Exception::Class qw/
1515
DB::Exception::UndefinedCourseField
1616
DB::Exception::InvalidCourseField
1717
DB::Exception::InvalidCourseFieldType
18-
);
18+
/;
1919

2020
use DateTime::TimeZone;
2121
use JSON::PP;
@@ -80,35 +80,34 @@ sub isValidSetting ($setting, $value = undef) {
8080
if ($setting->{type} eq 'text') {
8181
# any val is valid.
8282
} elsif ($setting->{type} eq 'boolean') {
83-
my $is_bool = JSON::PP::is_bool($val);
8483
DB::Exception::InvalidCourseFieldType->throw(
85-
message => qq/The variable $setting->{setting_name} has value $val and must be a boolean./)
86-
unless $is_bool;
84+
message => "The variable $setting->{setting_name} has value $val and must be a boolean.")
85+
unless JSON::PP::is_bool($val);
8786
} elsif ($setting->{type} eq 'list') {
8887
validateList($setting, $val);
8988
} elsif ($setting->{type} eq 'multilist') {
9089
validateMultilist($setting, $val);
9190
} elsif ($setting->{type} eq 'time') {
92-
DB::Exception::InvalidCourseFieldType->throw(message =>
93-
qq/The variable $setting->{setting_name} has value $val and must be a time in the form XX:XX/)
91+
DB::Exception::InvalidCourseFieldType->throw(
92+
message => "The variable $setting->{setting_name} has value $val and must be a time in the form XX:XX")
9493
unless isTimeString($val);
9594
} elsif ($setting->{type} eq 'int') {
9695
DB::Exception::InvalidCourseFieldType->throw(
97-
message => qq/The variable $setting->{setting_name} has value $val and must be an integer./)
96+
message => "The variable $setting->{setting_name} has value $val and must be an integer.")
9897
unless isInteger($val);
9998
} elsif ($setting->{type} eq 'decimal') {
10099
DB::Exception::InvalidCourseFieldType->throw(
101-
message => qq/The variable $setting->{setting_name} has value $val and must be a decimal/)
100+
message => "The variable $setting->{setting_name} has value $val and must be a decimal.")
102101
unless isDecimal($val);
103102
} elsif ($setting->{type} eq 'time_duration') {
104103
DB::Exception::InvalidCourseFieldType->throw(
105-
message => qq/The variable $setting->{setting_name} has value $val and must be a time duration/)
104+
message => "The variable $setting->{setting_name} has value $val and must be a time duration.")
106105
unless $val =~ /^\d+$/;
107106
} elsif ($setting->{type} eq 'timezone') {
108107
# try to make a new timeZone. If the name isn't valid an 'Invalid offset:' will be thrown.
109108
DateTime::TimeZone->new(name => $val);
110109
} else {
111-
DB::Exception::InvalidCourseFieldType->throw(message => qq/The setting type $setting->{type} is not valid/);
110+
DB::Exception::InvalidCourseFieldType->throw(message => "The setting type $setting->{type} is not valid.");
112111
}
113112
return 1;
114113
}

src/common/models/parsers.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,9 @@ export function parseString(_value: string | number | boolean) {
166166

167167
/**
168168
* Converts a time_duration type setting to a human-readable one.
169-
* TODO: use localization for this.
170169
* @params td - time duration in seconds.
171170
*/
172-
171+
// TODO: use localization for this.
173172
export const humanReadableTimeDuration = (td: number): string => {
174173
const times = {
175174
week: Math.floor(td / 604800),

0 commit comments

Comments
 (0)