diff --git a/app/coffeescripts/models/DateGroup.coffee b/app/coffeescripts/models/DateGroup.coffee index 21b55114a2f..3732b54ed46 100644 --- a/app/coffeescripts/models/DateGroup.coffee +++ b/app/coffeescripts/models/DateGroup.coffee @@ -3,7 +3,8 @@ define [ 'underscore' 'jquery' 'i18n!assignments' -], (Backbone, _, $, I18n) -> + 'timezone' +], (Backbone, _, $, I18n, tz) -> class DateGroup extends Backbone.Model @@ -15,19 +16,19 @@ define [ dueAt: -> dueAt = @get("due_at") - if dueAt then Date.parse(dueAt) else null + if dueAt then tz.parse(dueAt) else null unlockAt: -> unlockAt = @get("unlock_at") - if unlockAt then Date.parse(unlockAt) else null + if unlockAt then tz.parse(unlockAt) else null lockAt: -> lockAt = @get("lock_at") - if lockAt then Date.parse(lockAt) else null + if lockAt then tz.parse(lockAt) else null now: -> now = @get("now") - if now then Date.parse(now) else new Date() + if now then tz.parse(now) else new Date() # no lock/unlock dates @@ -61,4 +62,4 @@ define [ available: @available() pending: @pending() open: @open() - closed: @closed() \ No newline at end of file + closed: @closed() diff --git a/app/views/jst/assignments/CreateAssignment.handlebars b/app/views/jst/assignments/CreateAssignment.handlebars index 91f9164a3ac..263a1e4e6f9 100644 --- a/app/views/jst/assignments/CreateAssignment.handlebars +++ b/app/views/jst/assignments/CreateAssignment.handlebars @@ -57,7 +57,7 @@ {{#each allDates}}
{{dueFor}}
-
{{#if dueAt}} {{strftime dueAt "%b %-d"}} {{else}} - {{/if}}
+
{{#if dueAt}} {{tDateToString (fudge dueAt) 'short'}} {{else}} - {{/if}}
{{/each}} diff --git a/app/views/jst/assignments/DateDueColumnView.handlebars b/app/views/jst/assignments/DateDueColumnView.handlebars index 62d85a2cd2a..d65f8ddeadf 100644 --- a/app/views/jst/assignments/DateDueColumnView.handlebars +++ b/app/views/jst/assignments/DateDueColumnView.handlebars @@ -15,7 +15,7 @@
{{#if dueAt}} - {{strftime dueAt "%b %-d"}} + {{tDateToString (fudge dueAt) 'short'}} {{else}} - diff --git a/app/views/jst/assignments/_available_date_description.handlebars b/app/views/jst/assignments/_available_date_description.handlebars index 5ca814fe642..ee0c7324291 100644 --- a/app/views/jst/assignments/_available_date_description.handlebars +++ b/app/views/jst/assignments/_available_date_description.handlebars @@ -1,14 +1,14 @@ {{#if pending}} {{#t "not_available_until"}}Not available until{{/t}} - {{strftime unlockAt "%b %-d"}} + {{tDateToString (fudge unlockAt) 'short'}} {{/if}} {{#if open}} {{#t "available_until"}}Available until{{/t}} - {{strftime lockAt "%b %-d"}} + {{tDateToString (fudge lockAt) 'short'}} {{/if}} diff --git a/app/views/jst/calendar/agendaView.handlebars b/app/views/jst/calendar/agendaView.handlebars index b0d09ad43bc..a1ff418079d 100644 --- a/app/views/jst/calendar/agendaView.handlebars +++ b/app/views/jst/calendar/agendaView.handlebars @@ -23,11 +23,11 @@
{{#if assignment}} {{#t "due"}}Due{{/t}}, - {{strftime originalStart "%l:%M%P"}} + {{tTimeToString originalStart "tiny"}} {{else}} {{#unless all_day}} {{#t "starts_at"}}Starts at{{/t}}, - {{strftime originalStart "%l:%M%P"}} + {{tTimeToString originalStart "tiny"}} {{/unless}} {{/if}}
diff --git a/app/views/jst/feature_flags/featureFlag.handlebars b/app/views/jst/feature_flags/featureFlag.handlebars index a1cd7325f30..8aca8168424 100644 --- a/app/views/jst/feature_flags/featureFlag.handlebars +++ b/app/views/jst/feature_flags/featureFlag.handlebars @@ -22,7 +22,7 @@ {{#if releaseOn}} {{#t "estimated_release"}}Estimated Release:{{/t}} - {{strftime releaseOn "%B %-d, %Y"}} + {{tDateToString (fudge releaseOn) "medium"}} {{/if}} diff --git a/spec/coffeescripts/calendar/AgendaViewSpec.coffee b/spec/coffeescripts/calendar/AgendaViewSpec.coffee index 80eb68e2921..34d622669ce 100644 --- a/spec/coffeescripts/calendar/AgendaViewSpec.coffee +++ b/spec/coffeescripts/calendar/AgendaViewSpec.coffee @@ -3,11 +3,14 @@ define [ 'underscore' 'timezone' 'vendor/timezone/America/Denver' + 'vendor/timezone/America/Juneau' + 'vendor/timezone/fr_FR' 'compiled/views/calendar/AgendaView' 'compiled/calendar/EventDataSource' 'helpers/ajax_mocks/api/v1/calendarEvents' 'helpers/ajax_mocks/api/v1/calendarAssignments' -], ($, _, tz, denver, AgendaView, EventDataSource, eventResponse, assignmentResponse) -> + 'helpers/I18nStubber' +], ($, _, tz, denver, juneau, french, AgendaView, EventDataSource, eventResponse, assignmentResponse, I18nStubber) -> loadEventPage = (server, includeNext = false) -> sendCustomEvents(server, eventResponse, assignmentResponse, includeNext) @@ -28,11 +31,13 @@ define [ @server = sinon.fakeServer.create() @snapshot = tz.snapshot() tz.changeZone(denver, 'America/Denver') + I18nStubber.pushFrame() teardown: -> @container.remove() @server.restore() tz.restore(@snapshot) + I18nStubber.popFrame() test 'should render results', -> view = new AgendaView(el: @container, dataSource: @dataSource) @@ -57,6 +62,11 @@ define [ ok @container.find('.agenda-load-btn').length test 'toJSON should properly serialize results', -> + I18nStubber.stub 'en', + 'date.formats.short_with_weekday': '%a, %b %-d' + 'date.abbr_day_names.1': 'Mon' + 'date.abbr_month_names.10': 'Oct' + view = new AgendaView(el: @container, dataSource: @dataSource) view.fetch(@contextCodes, @startDate) loadEventPage(@server) @@ -101,3 +111,53 @@ define [ sendCustomEvents(@server, JSON.stringify(events), JSON.stringify([]), false, 2) ok @container.find('.ig-row').length == 60, 'finds 60 ig-rows' + + test 'renders non-assignment events with locale-appropriate format string', -> + tz.changeLocale(french, 'fr_FR') + I18nStubber.setLocale 'fr_FR' + I18nStubber.stub 'fr_FR', 'time.formats.tiny': '%k:%M' + + view = new AgendaView(el: @container, dataSource: @dataSource) + view.fetch(@contextCodes, @startDate) + loadEventPage(@server) + + # this event has a start_at of 2013-10-08T20:30:00Z, or 1pm MDT + ok @container.find('.ig-details').slice(2, 3).text().match(/13:00/), 'formats according to locale' + + test 'renders assignment events with locale-appropriate format string', -> + tz.changeLocale(french, 'fr_FR') + I18nStubber.setLocale 'fr_FR' + I18nStubber.stub 'fr_FR', 'time.formats.tiny': '%k:%M' + + view = new AgendaView(el: @container, dataSource: @dataSource) + view.fetch(@contextCodes, @startDate) + loadEventPage(@server) + + # this event has a start_at of 2013-10-13T05:59:59Z, or 11:59pm MDT + ok @container.find('.ig-details').slice(12, 13).text().match(/23:59/), 'formats according to locale' + + test 'renders non-assignment events in appropriate timezone', -> + tz.changeZone(juneau, 'America/Juneau') + I18nStubber.stub 'en', + 'time.formats.tiny': '%l:%M%P' + 'date': {} + + view = new AgendaView(el: @container, dataSource: @dataSource) + view.fetch(@contextCodes, @startDate) + loadEventPage(@server) + + # this event has a start_at of 2013-10-08T20:30:00Z, or 11:00am AKDT + ok @container.find('.ig-details').slice(2, 3).text().match(/11:00am/), 'formats in correct timezone' + + test 'renders assignment events in appropriate timezone', -> + tz.changeZone(juneau, 'America/Juneau') + I18nStubber.stub 'en', + 'time.formats.tiny': '%l:%M%P' + 'date': {} + + view = new AgendaView(el: @container, dataSource: @dataSource) + view.fetch(@contextCodes, @startDate) + loadEventPage(@server) + + # this event has a start_at of 2013-10-13T05:59:59Z, or 9:59pm AKDT + ok @container.find('.ig-details').slice(12, 13).text().match(/9:59pm/), 'formats in correct timezone' diff --git a/spec/coffeescripts/views/assignments/AssignmentListItemViewSpec.coffee b/spec/coffeescripts/views/assignments/AssignmentListItemViewSpec.coffee index 1a1b653f610..9ec31bd1d18 100644 --- a/spec/coffeescripts/views/assignments/AssignmentListItemViewSpec.coffee +++ b/spec/coffeescripts/views/assignments/AssignmentListItemViewSpec.coffee @@ -4,9 +4,13 @@ define [ 'compiled/models/Submission' 'compiled/views/assignments/AssignmentListItemView' 'jquery' + 'timezone' + 'vendor/timezone/America/Juneau' + 'vendor/timezone/fr_FR' + 'helpers/I18nStubber' 'helpers/fakeENV' 'helpers/jquery.simulate' -], (Backbone, Assignment, Submission, AssignmentListItemView, $, fakeENV) -> +], (Backbone, Assignment, Submission, AssignmentListItemView, $, tz, juneau, french, I18nStubber, fakeENV) -> screenreaderText = null nonScreenreaderText = null @@ -144,9 +148,15 @@ define [ setup: -> genSetup.call @ + @snapshot = tz.snapshot() + I18nStubber.pushFrame() + teardown: -> genTeardown.call @ + tz.restore(@snapshot) + I18nStubber.popFrame() + test "initializes child views if can manage", -> view = createView(@model, canManage: true) ok view.publishIconView @@ -310,6 +320,57 @@ define [ equal spy.callCount, 0 AssignmentListItemView.prototype.updateScore.restore() + test "renders lockAt/unlockAt with locale-appropriate format string", -> + tz.changeLocale(french, 'fr_FR') + I18nStubber.setLocale 'fr_FR' + I18nStubber.stub 'fr_FR', + 'date.formats.short': '%-d %b' + 'date.abbr_month_names.8': 'août' + model = new AssignmentCollection([buildAssignment + id: 1 + all_dates: [ + { lock_at: "2113-08-28T04:00:00Z", title: "Summer Session" } + { unlock_at: "2113-08-28T04:00:00Z", title: "Winter Session" }]]).at(0) + + view = createView(model, canManage: true) + $dds = view.dateAvailableColumnView.$("#vdd_tooltip_#{@model.id}_lock div") + equal $("span", $dds.first()).last().text().trim(), '28 août' + equal $("span", $dds.last()).last().text().trim(), '28 août' + + test "renders lockAt/unlockAt in appropriate time zone", -> + tz.changeZone(juneau, 'America/Juneau') + I18nStubber.stub 'en', + 'date.formats.short': '%b %-d' + 'date.abbr_month_names.8': 'Aug' + + model = new AssignmentCollection([buildAssignment + id: 1 + all_dates: [ + { lock_at: "2113-08-28T04:00:00Z", title: "Summer Session" } + { unlock_at: "2113-08-28T04:00:00Z", title: "Winter Session" }]]).at(0) + + view = createView(model, canManage: true) + $dds = view.dateAvailableColumnView.$("#vdd_tooltip_#{@model.id}_lock div") + equal $("span", $dds.first()).last().text().trim(), 'Aug 27' + equal $("span", $dds.last()).last().text().trim(), 'Aug 27' + + test "renders due date column with locale-appropriate format string", -> + tz.changeLocale(french, 'fr_FR') + I18nStubber.setLocale 'fr_FR' + I18nStubber.stub 'fr_FR', + 'date.formats.short': '%-d %b' + 'date.abbr_month_names.8': 'août' + view = createView(@model, canManage: true) + equal view.dateDueColumnView.$("#vdd_tooltip_#{@model.id}_due div dd").first().text().trim(), '29 août' + + test "renders due date column in appropriate time zone", -> + tz.changeZone(juneau, 'America/Juneau') + I18nStubber.stub 'en', + 'date.formats.short': '%b %-d' + 'date.abbr_month_names.8': 'Aug' + view = createView(@model, canManage: true) + equal view.dateDueColumnView.$("#vdd_tooltip_#{@model.id}_due div dd").first().text().trim(), 'Aug 28' + module 'AssignmentListItemViewSpec—alternate grading type: percent', setup: -> genSetup.call @, assignment_grade_percent() diff --git a/spec/coffeescripts/views/assignments/CreateAssignmentViewSpec.coffee b/spec/coffeescripts/views/assignments/CreateAssignmentViewSpec.coffee index 1d484ff2cbf..b7e90f0ffd9 100644 --- a/spec/coffeescripts/views/assignments/CreateAssignmentViewSpec.coffee +++ b/spec/coffeescripts/views/assignments/CreateAssignmentViewSpec.coffee @@ -6,9 +6,13 @@ define [ 'compiled/views/assignments/CreateAssignmentView' 'compiled/views/DialogFormView' 'jquery' + 'timezone' + 'vendor/timezone/America/Juneau' + 'vendor/timezone/fr_FR' + 'helpers/I18nStubber' 'helpers/jquery.simulate' 'compiled/behaviors/tooltip' -], (Backbone, AssignmentGroupCollection, AssignmentGroup, Assignment, CreateAssignmentView, DialogFormView, $) -> +], (Backbone, AssignmentGroupCollection, AssignmentGroup, Assignment, CreateAssignmentView, DialogFormView, $, tz, juneau, french, I18nStubber) -> fixtures = $('#fixtures') @@ -113,12 +117,18 @@ define [ @assignment4 = assignment4() @group = assignmentGroup() + @snapshot = tz.snapshot() + I18nStubber.pushFrame() + teardown: -> ENV.VALID_DATE_RANGE = { start_at: {date: null, date_context: null} end_at: {date: null, date_context: null} } + tz.restore(@snapshot) + I18nStubber.popFrame() + test "initialize generates a new assignment for creation", -> view = createView(@group) equal view.model.get("assignment_group_id"), @group.get("id") @@ -297,3 +307,19 @@ define [ ok errors["due_at"] equal errors['due_at'][0]['message'], 'Due date cannot be before unlock date' + test "renders due dates with locale-appropriate format string", -> + tz.changeLocale(french, 'fr_FR') + I18nStubber.setLocale 'fr_FR' + I18nStubber.stub 'fr_FR', + 'date.formats.short': '%-d %b' + 'date.abbr_month_names.8': 'août' + view = createView(@assignment1) + equal view.$("#vdd_tooltip_assign_1 div dd").first().text().trim(), '28 août' + + test "renders due dates in appropriate time zone", -> + tz.changeZone(juneau, 'America/Juneau') + I18nStubber.stub 'en', + 'date.formats.short': '%b %-d' + 'date.abbr_month_names.8': 'Aug' + view = createView(@assignment1) + equal view.$("#vdd_tooltip_assign_1 div dd").first().text().trim(), 'Aug 27' diff --git a/spec/coffeescripts/views/feature_flags/FeatureFlagViewSpec.coffee b/spec/coffeescripts/views/feature_flags/FeatureFlagViewSpec.coffee new file mode 100644 index 00000000000..701b284b344 --- /dev/null +++ b/spec/coffeescripts/views/feature_flags/FeatureFlagViewSpec.coffee @@ -0,0 +1,58 @@ +define [ + 'compiled/views/feature_flags/FeatureFlagView' + 'compiled/models/FeatureFlag' + 'jquery' + 'timezone' + 'vendor/timezone/America/Juneau' + 'vendor/timezone/fr_FR' + 'helpers/I18nStubber' + 'helpers/fakeENV' +], (FeatureFlagView, FeatureFlag, $, tz, juneau, french, I18nStubber, fakeENV) -> + + module "FeatureFlagView", + setup: -> + @container = $('
', id: 'feature-flags').appendTo('#fixtures') + @snapshot = tz.snapshot() + I18nStubber.pushFrame() + fakeENV.setup() + + teardown: -> + @container.remove() + tz.restore(@snapshot) + I18nStubber.popFrame() + fakeENV.teardown() + + test 'should format release date with locale-appropriate format string', -> + releaseDate = tz.parse('2100-07-04T00:00:00Z') + + tz.changeLocale(french, 'fr_FR') + I18nStubber.setLocale 'fr_FR' + I18nStubber.stub 'fr_FR', + 'date.formats.medium': '%-d %b %Y' + 'date.abbr_month_names.7': 'juil.' + + flag = new FeatureFlag + releaseOn: releaseDate + feature_flag: + transitions: {} + view = new FeatureFlagView el: @container, model: flag + view.render() + + equal view.$('.feature-release-date').text().trim(), '4 juil. 2100' + + test 'should format release date in locale-appropriate format string', -> + releaseDate = tz.parse('2100-07-04T00:00:00Z') + + tz.changeZone(juneau, 'America/Juneau') + I18nStubber.stub 'en', + 'date.formats.medium': '%b %-d, %Y' + 'date.abbr_month_names.7': 'Jul' + + flag = new FeatureFlag + releaseOn: releaseDate + feature_flag: + transitions: {} + view = new FeatureFlagView el: @container, model: flag + view.render() + + equal view.$('.feature-release-date').text().trim(), 'Jul 3, 2100'