diff --git a/app/controllers/admin/discourse_calendar/admin_holidays_controller.rb b/app/controllers/admin/discourse_calendar/admin_holidays_controller.rb
index f59c85d7..07d4bb6c 100644
--- a/app/controllers/admin/discourse_calendar/admin_holidays_controller.rb
+++ b/app/controllers/admin/discourse_calendar/admin_holidays_controller.rb
@@ -1,19 +1,41 @@
# frozen_string_literal: true
-require "holidays"
-
module Admin::DiscourseCalendar
class AdminHolidaysController < AdminDiscourseCalendarController
def index
region_code = params[:region_code]
begin
- holidays = Holidays.year_holidays([region_code], Time.current.beginning_of_year)
+ holidays = DiscourseCalendar::Holiday.find_holidays_for(region_code: region_code)
rescue Holidays::InvalidRegion
return render_json_error(I18n.t("system_messages.discourse_calendar_holiday_region_invalid"), 422)
end
render json: { region_code: region_code, holidays: holidays }
end
+
+ def disable
+ DiscourseCalendar::DisabledHoliday.create!(disabled_holiday_params)
+ CalendarEvent.destroy_by(
+ description: disabled_holiday_params[:holiday_name],
+ region: disabled_holiday_params[:region_code]
+ )
+
+ render json: success_json
+ end
+
+ def enable
+ if DiscourseCalendar::DisabledHoliday.destroy_by(disabled_holiday_params).present?
+ render json: success_json
+ else
+ render_json_error(I18n.t("system_messages.discourse_calendar_enable_holiday_failed"), 422)
+ end
+ end
+
+ private
+
+ def disabled_holiday_params
+ params.require(:disabled_holiday).permit(:holiday_name, :region_code)
+ end
end
end
diff --git a/app/models/discourse_calendar/disabled_holiday.rb b/app/models/discourse_calendar/disabled_holiday.rb
new file mode 100644
index 00000000..e8407883
--- /dev/null
+++ b/app/models/discourse_calendar/disabled_holiday.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module DiscourseCalendar
+ class DisabledHoliday < ActiveRecord::Base
+ validates :holiday_name, presence: true
+ validates :region_code, presence: true
+ end
+end
+
+# == Schema Information
+#
+# Table name: discourse_calendar_disabled_holidays
+#
+# id :bigint not null, primary key
+# holiday_name :string not null
+# region_code :string not null
+# disabled :boolean default(TRUE), not null
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+# Indexes
+#
+# index_disabled_holidays_on_holiday_name_and_region_code (holiday_name,region_code)
+#
diff --git a/app/models/discourse_post_event/event.rb b/app/models/discourse_post_event/event.rb
index 4b838da1..878b3c8f 100644
--- a/app/models/discourse_post_event/event.rb
+++ b/app/models/discourse_post_event/event.rb
@@ -371,3 +371,21 @@ module DiscoursePostEvent
end
end
end
+
+# == Schema Information
+#
+# Table name: discourse_post_event_events
+#
+# id :bigint not null, primary key
+# status :integer default(0), not null
+# original_starts_at :datetime not null
+# original_ends_at :datetime
+# deleted_at :datetime
+# raw_invitees :string is an Array
+# name :string
+# url :string(1000)
+# custom_fields :jsonb not null
+# reminders :string
+# recurrence :string
+# timezone :string
+#
diff --git a/app/models/discourse_post_event/invitee.rb b/app/models/discourse_post_event/invitee.rb
index 0fc2b237..27ea4335 100644
--- a/app/models/discourse_post_event/invitee.rb
+++ b/app/models/discourse_post_event/invitee.rb
@@ -69,3 +69,20 @@ module DiscoursePostEvent
end
end
end
+
+# == Schema Information
+#
+# Table name: discourse_post_event_invitees
+#
+# id :bigint not null, primary key
+# post_id :integer not null
+# user_id :integer not null
+# status :integer
+# created_at :datetime not null
+# updated_at :datetime not null
+# notified :boolean default(FALSE), not null
+#
+# Indexes
+#
+# discourse_post_event_invitees_post_id_user_id_idx (post_id,user_id) UNIQUE
+#
diff --git a/app/services/discourse_calendar/holiday.rb b/app/services/discourse_calendar/holiday.rb
new file mode 100644
index 00000000..0b837b2b
--- /dev/null
+++ b/app/services/discourse_calendar/holiday.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require "holidays"
+
+module DiscourseCalendar
+ class Holiday
+ def self.find_holidays_for(
+ region_code:,
+ start_date: Date.current.beginning_of_year,
+ end_date: Date.current.end_of_year,
+ show_holiday_observed_on_dates: false)
+
+ holidays = Holidays.between(
+ start_date,
+ end_date,
+ [region_code],
+ show_holiday_observed_on_dates ? :observed : [])
+
+ holidays.map do |holiday|
+ holiday[:disabled] = DiscourseCalendar::DisabledHoliday
+ .where(region_code: region_code)
+ .exists?(holiday_name: holiday[:name])
+ end
+
+ holidays
+ end
+ end
+end
diff --git a/assets/javascripts/discourse/components/admin-holidays-list-item.js b/assets/javascripts/discourse/components/admin-holidays-list-item.js
new file mode 100644
index 00000000..e35b80ec
--- /dev/null
+++ b/assets/javascripts/discourse/components/admin-holidays-list-item.js
@@ -0,0 +1,47 @@
+import Component from "@ember/component";
+import { action } from "@ember/object";
+import { ajax } from "discourse/lib/ajax";
+import { popupAjaxError } from "discourse/lib/ajax-error";
+
+export default Component.extend({
+ tagName: "tr",
+ classNameBindings: ["isHolidayDisabled:disabled"],
+ loading: false,
+ isHolidayDisabled: false,
+
+ @action
+ disableHoliday(holiday, region_code) {
+ if (this.loading) {
+ return;
+ }
+
+ this.set("loading", true);
+
+ return ajax({
+ url: `/admin/discourse-calendar/holidays/disable`,
+ type: "POST",
+ data: { disabled_holiday: { holiday_name: holiday.name, region_code } },
+ })
+ .then(() => this.set("isHolidayDisabled", true))
+ .catch(popupAjaxError)
+ .finally(() => this.set("loading", false));
+ },
+
+ @action
+ enableHoliday(holiday, region_code) {
+ if (this.loading) {
+ return;
+ }
+
+ this.set("loading", true);
+
+ return ajax({
+ url: `/admin/discourse-calendar/holidays/enable`,
+ type: "DELETE",
+ data: { disabled_holiday: { holiday_name: holiday.name, region_code } },
+ })
+ .then(() => this.set("isHolidayDisabled", false))
+ .catch(popupAjaxError)
+ .finally(() => this.set("loading", false));
+ },
+});
diff --git a/assets/javascripts/discourse/templates/admin-plugins-calendar.hbs b/assets/javascripts/discourse/templates/admin-plugins-calendar.hbs
index e9d42962..55c4db5d 100644
--- a/assets/javascripts/discourse/templates/admin-plugins-calendar.hbs
+++ b/assets/javascripts/discourse/templates/admin-plugins-calendar.hbs
@@ -1,12 +1,23 @@
-
{{i18n "discourse_calendar.holidays"}}
+
+ {{i18n "discourse_calendar.holidays.header_title"}}
+
{{region-input
value=this.selectedRegion
onChange=(action "getHolidays")
}}
+
+ {{i18n "discourse_calendar.holidays.pick_region_description"}}
+
+ {{i18n "discourse_calendar.holidays.disabled_holidays_description"}}
+
+
{{conditional-loading-spinner condition=loading}}
{{#if model.holidays}}
- {{admin-holidays-list holidays=model.holidays}}
+ {{admin-holidays-list
+ holidays=model.holidays
+ region_code=this.selectedRegion
+ }}
{{/if}}
diff --git a/assets/javascripts/discourse/templates/components/admin-holidays-list-item.hbs b/assets/javascripts/discourse/templates/components/admin-holidays-list-item.hbs
new file mode 100644
index 00000000..b6324a04
--- /dev/null
+++ b/assets/javascripts/discourse/templates/components/admin-holidays-list-item.hbs
@@ -0,0 +1,15 @@
+{{holiday.date}} |
+{{holiday.name}} |
+
+ {{#if isHolidayDisabled}}
+ {{d-button
+ action=(action "enableHoliday" holiday region_code)
+ label="discourse_calendar.enable_holiday"
+ }}
+ {{else}}
+ {{d-button
+ action=(action "disableHoliday" holiday region_code)
+ label="discourse_calendar.disable_holiday"
+ }}
+ {{/if}}
+ |
diff --git a/assets/javascripts/discourse/templates/components/admin-holidays-list.hbs b/assets/javascripts/discourse/templates/components/admin-holidays-list.hbs
index 5bfcf64e..32ef225e 100644
--- a/assets/javascripts/discourse/templates/components/admin-holidays-list.hbs
+++ b/assets/javascripts/discourse/templates/components/admin-holidays-list.hbs
@@ -2,16 +2,17 @@
| {{i18n "discourse_calendar.date"}} |
- {{i18n "discourse_calendar.holiday"}} |
+ {{i18n "discourse_calendar.holiday"}} |
{{#each @holidays as |holiday|}}
-
- | {{holiday.date}} |
- {{holiday.name}} |
-
+ {{admin-holidays-list-item
+ holiday=holiday
+ isHolidayDisabled=holiday.disabled
+ region_code=region_code
+ }}
{{/each}}
diff --git a/assets/stylesheets/common/discourse-calendar-holidays.scss b/assets/stylesheets/common/discourse-calendar-holidays.scss
index 22a53d87..02b33238 100644
--- a/assets/stylesheets/common/discourse-calendar-holidays.scss
+++ b/assets/stylesheets/common/discourse-calendar-holidays.scss
@@ -1,3 +1,9 @@
.region-input {
width: 50%;
}
+
+.disabled td {
+ background-color: var(--primary-very-low);
+ color: var(--primary-medium);
+ font-style: italic;
+}
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 89d3040e..f3736640 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -20,8 +20,13 @@ en:
discourse_calendar:
invite_user_notification: "%{username} invited you to: %{description}"
on_holiday: "On Holiday"
+ disable_holiday: "Disable"
+ enable_holiday: "Enable"
holiday: "Holiday"
- holidays: "Holidays"
+ holidays:
+ header_title: "Holidays"
+ pick_region_description: "Pick a region to see the holidays for that region."
+ disabled_holidays_description: "Disabled holidays will be excluded from the staff holiday calendar."
date: "Date"
add_to_calendar: "Add to Google Calendar"
region:
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 6dff344b..fb496fc3 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -11,6 +11,7 @@ en:
title: Event started
system_messages:
discourse_calendar_holiday_region_invalid: "The holiday region you provided does not exist."
+ discourse_calendar_enable_holiday_failed: "This holiday could not be enabled, it's already enabled or it's not disabled."
discourse_post_event_bulk_invite_succeeded:
title: "Event - Bulk Invite Succeeded"
subject_template: "Bulk invite processed successfully"
diff --git a/db/migrate/20220604200919_create_disabled_holidays.rb b/db/migrate/20220604200919_create_disabled_holidays.rb
new file mode 100644
index 00000000..92df3587
--- /dev/null
+++ b/db/migrate/20220604200919_create_disabled_holidays.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class CreateDisabledHolidays < ActiveRecord::Migration[7.0]
+ def change
+ create_table :discourse_calendar_disabled_holidays do |t|
+ t.string :holiday_name, null: false
+ t.string :region_code, null: false
+ t.boolean :disabled, null: false, default: true
+
+ t.timestamps
+ end
+
+ add_index :discourse_calendar_disabled_holidays, [:holiday_name, :region_code], name: 'index_disabled_holidays_on_holiday_name_and_region_code'
+ end
+end
diff --git a/jobs/scheduled/create_holiday_events.rb b/jobs/scheduled/create_holiday_events.rb
index f6785b25..1f6403cf 100644
--- a/jobs/scheduled/create_holiday_events.rb
+++ b/jobs/scheduled/create_holiday_events.rb
@@ -40,9 +40,13 @@ module Jobs
.delete_all
regions_and_user_ids.each do |region, user_ids|
- Holidays
- .between(Date.today, 6.months.from_now, [region], :observed)
- .filter { |holiday| (1..5) === holiday[:date].wday }
+ DiscourseCalendar::Holiday.find_holidays_for(
+ region_code: region,
+ start_date: Date.today,
+ end_date: 6.months.from_now,
+ show_holiday_observed_on_dates: true
+ )
+ .filter { |holiday| (1..5) === holiday[:date].wday && holiday[:disabled] === false }
.each do |holiday|
user_ids.each do |user_id|
diff --git a/plugin.rb b/plugin.rb
index 01c5f848..1ce8e461 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -85,13 +85,15 @@ after_initialize do
end
end
- # DISCOURSE CALENDAR
+ # DISCOURSE CALENDAR HOLIDAYS
add_admin_route 'admin.calendar', 'calendar'
%w[
../app/controllers/admin/admin_discourse_calendar_controller.rb
../app/controllers/admin/discourse_calendar/admin_holidays_controller.rb
+ ../app/models/discourse_calendar/disabled_holiday.rb
+ ../app/services/discourse_calendar/holiday.rb
].each { |path| load File.expand_path(path, __FILE__) }
Discourse::Application.routes.append do
@@ -99,6 +101,8 @@ after_initialize do
get '/admin/plugins/calendar' => 'admin/plugins#index', constraints: StaffConstraint.new
get '/admin/discourse-calendar/holiday-regions/:region_code/holidays' => 'admin/discourse_calendar/admin_holidays#index', constraints: StaffConstraint.new
+ post '/admin/discourse-calendar/holidays/disable' => 'admin/discourse_calendar/admin_holidays#disable', constraints: StaffConstraint.new
+ delete '/admin/discourse-calendar/holidays/enable' => 'admin/discourse_calendar/admin_holidays#enable', constraints: StaffConstraint.new
end
# DISCOURSE POST EVENT
diff --git a/spec/jobs/scheduled/create_holiday_events_spec.rb b/spec/jobs/scheduled/create_holiday_events_spec.rb
index a2cc2e81..3f74cd9c 100644
--- a/spec/jobs/scheduled/create_holiday_events_spec.rb
+++ b/spec/jobs/scheduled/create_holiday_events_spec.rb
@@ -84,6 +84,37 @@ describe DiscourseCalendar::CreateHolidayEvents do
expect(CalendarEvent.exists?(username: frenchy.username)).to eq(false)
end
+ context "when there are disabled holidays" do
+ let(:france_assomption) { { holiday_name: "Assomption", region_code: "fr" } }
+ let(:france_toussaint) { { holiday_name: "Toussaint", region_code: "fr" } }
+
+ before do
+ DiscourseCalendar::DisabledHoliday.create!(france_assomption)
+ DiscourseCalendar::DisabledHoliday.create!(france_toussaint)
+ end
+
+ it "only adds enabled holidays to the calendar" do
+ frenchy
+ freeze_time Time.zone.local(2019, 7, 1)
+ subject.execute(nil)
+
+ expect(CalendarEvent.pluck(:region, :description, :start_date, :username)).to eq([
+ ["fr", "Armistice 1918", "2019-11-11", frenchy.username],
+ ["fr", "Noël", "2019-12-25", frenchy.username],
+ ["fr", "Jour de l'an", "2020-01-01", frenchy.username]
+ ])
+ end
+
+ it "doesn't add disabled holidays to the calendar" do
+ frenchy
+ freeze_time Time.zone.local(2019, 7, 1)
+ subject.execute(nil)
+
+ expect(CalendarEvent.pluck(:description)).not_to include(france_assomption[:holiday_name])
+ expect(CalendarEvent.pluck(:description)).not_to include(france_toussaint[:holiday_name])
+ end
+ end
+
context "when user_options.timezone column exists" do
it "uses the user TZ when available" do
frenchy.user_option.update!(timezone: "Europe/Paris")
diff --git a/spec/requests/admin/admin_holidays_controller_spec.rb b/spec/requests/admin/admin_holidays_controller_spec.rb
index 51792eac..96d3a7db 100644
--- a/spec/requests/admin/admin_holidays_controller_spec.rb
+++ b/spec/requests/admin/admin_holidays_controller_spec.rb
@@ -24,8 +24,8 @@ module Admin::DiscourseCalendar
get "/admin/discourse-calendar/holiday-regions/mx/holidays.json"
expect(response.parsed_body["holidays"]).to include(
- { "date" => "2022-01-01", "name" => "Año nuevo", "regions" => ["mx"] },
- { "date" => "2022-09-16", "name" => "Día de la Independencia", "regions" => ["mx"] }
+ { "date" => "2022-01-01", "name" => "Año nuevo", "regions" => ["mx"], "disabled" => false },
+ { "date" => "2022-09-16", "name" => "Día de la Independencia", "regions" => ["mx"], "disabled" => false }
)
end
@@ -65,5 +65,126 @@ module Admin::DiscourseCalendar
end
end
end
+
+ describe "#disable" do
+ context "when the calendar plugin is enabled" do
+ let(:calendar_enabled) { true }
+ let(:dia_de_la_independencia) do
+ { holiday_name: "Día de la Independencia", region_code: "mx" }
+ end
+
+ context "when an admin is signed in" do
+ before do
+ sign_in(admin)
+ end
+
+ it "disables the holiday in the specified region and returns a 200 status code" do
+ post "/admin/discourse-calendar/holidays/disable.json",
+ params: {
+ disabled_holiday: dia_de_la_independencia
+ }
+
+ disabled_holiday = DiscourseCalendar::DisabledHoliday.last
+
+ expect(disabled_holiday.holiday_name).to eq(dia_de_la_independencia[:holiday_name])
+ expect(disabled_holiday.region_code).to eq(dia_de_la_independencia[:region_code])
+ expect(disabled_holiday.disabled).to eq(true)
+ expect(response.status).to eq(200)
+ end
+
+ it "returns a 400 (bad request) status code when the parameters are not valid" do
+ post "/admin/discourse-calendar/holidays/disable.json",
+ params: { disabled_holiday: {} }
+
+ expect(response.status).to eq(400)
+ end
+
+ context "when a holiday has been added to the calendar" do
+ let(:calendar_post) { create_post(raw: "[calendar]\n[/calendar]") }
+ let(:australia_new_years_day) do
+ { holiday_name: "New Year's Day", date: "2022-01-01", region_code: "au" }
+ end
+ let(:australia_day) do
+ { holiday_name: "Australia Day", date: "2022-01-26", region_code: "au" }
+ end
+
+ before do
+ CalendarEvent.create!(
+ topic_id: calendar_post.topic_id,
+ description: australia_new_years_day[:holiday_name],
+ start_date: australia_new_years_day[:date],
+ region: australia_new_years_day[:region_code]
+ )
+
+ CalendarEvent.create!(
+ topic_id: calendar_post.topic_id,
+ description: australia_day[:holiday_name],
+ start_date: australia_day[:date],
+ region: australia_day[:region_code]
+ )
+ end
+
+ it "removes disabled holidays from the calendar" do
+ post "/admin/discourse-calendar/holidays/disable.json",
+ params: {
+ disabled_holiday: {
+ holiday_name: australia_new_years_day[:holiday_name],
+ region_code: australia_new_years_day[:region_code],
+ }
+ }
+
+ expect(CalendarEvent.where(
+ description: australia_new_years_day[:holiday_name],
+ region: australia_new_years_day[:region_code]
+ ).count).to eq(0)
+
+ expect(CalendarEvent.where(
+ description: australia_day[:holiday_name],
+ region: australia_day[:region_code]
+ ).count).to eq(1)
+ end
+ end
+ end
+ end
+ end
+
+ describe "#enable" do
+ context "when the calendar plugin is enabled" do
+ let(:calendar_enabled) { true }
+
+ context "when an admin is signed in" do
+ before do
+ sign_in(admin)
+ end
+
+ context "when there is a disabled holiday" do
+ let(:hong_kong_labour_day) { { holiday_name: "Labour Day", region_code: "hk" } }
+
+ before do
+ DiscourseCalendar::DisabledHoliday.create!(hong_kong_labour_day)
+ end
+
+ it "enables a holiday (by deleting its 'disabled' record) and returns a 200 status code" do
+ expect(DiscourseCalendar::DisabledHoliday.count).to eq(1)
+
+ delete "/admin/discourse-calendar/holidays/enable.json",
+ params: {
+ disabled_holiday: hong_kong_labour_day
+ }
+
+ expect(DiscourseCalendar::DisabledHoliday.count).to eq(0)
+ expect(response.status).to eq(200)
+ end
+ end
+
+ it "returns a 422 (unprocessable enity) status code when a holiday can't be enabled" do
+ delete "/admin/discourse-calendar/holidays/enable.json",
+ params: { disabled_holiday: { holiday_name: "Not disabled holiday", region_code: "NA" } }
+
+ expect(response.status).to eq(422)
+ end
+ end
+ end
+ end
end
end
diff --git a/spec/services/discouse-calendar/holiday_spec.rb b/spec/services/discouse-calendar/holiday_spec.rb
new file mode 100644
index 00000000..8badb3f3
--- /dev/null
+++ b/spec/services/discouse-calendar/holiday_spec.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+require "rails_helper"
+
+module DiscourseCalendar
+ describe Holiday do
+ describe ".find_holidays_for" do
+ before do
+ DisabledHoliday.create!(holiday_name: "New Year's Day", region_code: "sg")
+ DisabledHoliday.create!(holiday_name: "Chinese New Year", region_code: "sg")
+ end
+
+ let(:holidays) do
+ Holiday.find_holidays_for(
+ region_code: "sg",
+ start_date: "2022-01-01",
+ end_date: "2022-04-30"
+ )
+ end
+
+ it "returns a list of holidays indicating whether a holiday is disabled or not" do
+ expect(holidays).to include(a_hash_including(
+ { name: "New Year's Day", regions: [:sg], disabled: true }
+ ))
+
+ expect(holidays).to include(a_hash_including(
+ { name: "Chinese New Year", regions: [:sg], disabled: true }
+ ))
+
+ expect(holidays).to include(a_hash_including(
+ { name: "Good Friday", regions: [:sg], disabled: false }
+ ))
+ end
+
+ describe "dates holidays are observed on" do
+ let(:holidays) { Holiday.find_holidays_for(
+ region_code: "sg",
+ start_date: "2021-12-31",
+ end_date: "2022-05-31",
+ show_holiday_observed_on_dates: show_holiday_observed_on_dates) }
+
+ context "when `show_holiday_observed_on_dates` is set to true" do
+ let(:show_holiday_observed_on_dates) { true }
+
+ it "returns the holidays with the date the holidays are observed on" do
+ expect(holidays).to include(a_hash_including(
+ { name: "New Year's Day", date: Date.new(2021, 12, 31), regions: [:sg] }
+ ))
+
+ expect(holidays).to include(a_hash_including(
+ { name: "Labour Day", date: Date.new(2022, 5, 2), regions: [:sg] }
+ ))
+ end
+ end
+
+ context "when `show_holiday_observed_on_dates` is set to false" do
+ let(:show_holiday_observed_on_dates) { false }
+
+ it "returns the holidays with the actual holiday dates" do
+ expect(holidays).to include(a_hash_including(
+ { name: "New Year's Day", date: Date.new(2022, 1, 1), regions: [:sg] }
+ ))
+
+ expect(holidays).to include(a_hash_including(
+ { name: "Labour Day", date: Date.new(2022, 5, 1), regions: [:sg] }
+ ))
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/test/javascripts/acceptance/admin-calendar-test.js b/test/javascripts/acceptance/admin-holidays-test.js
similarity index 57%
rename from test/javascripts/acceptance/admin-calendar-test.js
rename to test/javascripts/acceptance/admin-holidays-test.js
index 4abac452..894cef8c 100644
--- a/test/javascripts/acceptance/admin-calendar-test.js
+++ b/test/javascripts/acceptance/admin-holidays-test.js
@@ -1,9 +1,9 @@
import { acceptance, query } from "discourse/tests/helpers/qunit-helpers";
import { test } from "qunit";
-import { visit } from "@ember/test-helpers";
+import { click, visit } from "@ember/test-helpers";
import selectKit from "discourse/tests/helpers/select-kit-helper";
-acceptance("Admin - Calendar", function (needs) {
+acceptance("Admin - Discourse Calendar - Holidays", function (needs) {
needs.user();
needs.settings({
calendar_enabled: true,
@@ -19,6 +19,14 @@ acceptance("Admin - Calendar", function (needs) {
],
});
});
+
+ server.post("/admin/discourse-calendar/holidays/disable", () => {
+ return helper.response({ success: "OK" });
+ });
+
+ server.delete("/admin/discourse-calendar/holidays/enable", () => {
+ return helper.response({ success: "OK" });
+ });
});
test("viewing holidays for a selected region", async (assert) => {
@@ -46,4 +54,24 @@ acceptance("Admin - Calendar", function (needs) {
"it displays holiday dates"
);
});
+
+ test("disabling and enabling a holiday", async (assert) => {
+ const regions = selectKit(".region-input");
+
+ await visit("/admin/plugins/calendar");
+ await regions.expand();
+ await regions.selectRowByValue("ca");
+
+ await click("table tr:first-child button");
+ assert.ok(
+ query("table tr.disabled:first-child"),
+ "after clicking the disable button, it adds a .disabled CSS class"
+ );
+
+ await click("table tr.disabled:first-child button");
+ assert.ok(
+ query("table tr:first-child"),
+ "after clicking the enable button, it removes the .disabled CSS class"
+ );
+ });
});
diff --git a/test/javascripts/integration/components/admin-holidays-list-item-test.js b/test/javascripts/integration/components/admin-holidays-list-item-test.js
new file mode 100644
index 00000000..c9f72855
--- /dev/null
+++ b/test/javascripts/integration/components/admin-holidays-list-item-test.js
@@ -0,0 +1,71 @@
+import componentTest, {
+ setupRenderingTest,
+} from "discourse/tests/helpers/component-test";
+import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers";
+import hbs from "htmlbars-inline-precompile";
+
+discourseModule(
+ "Integration | Component | admin-holidays-list-item",
+ function (hooks) {
+ setupRenderingTest(hooks);
+
+ const template = hbs`{{admin-holidays-list-item
+ holiday=holiday
+ region_code=region_code
+ isHolidayDisabled=holiday.disabled
+ }}`;
+
+ componentTest(
+ "when a holiday is disabled, it displays an enable button and adds a disabled CSS class",
+ {
+ template,
+
+ beforeEach() {
+ this.set("holiday", {
+ date: "2022-01-01",
+ name: "New Year's Day",
+ disabled: true,
+ });
+ this.set("region_code", "sg");
+ },
+
+ async test(assert) {
+ assert.equal(
+ query("button").innerText,
+ "Enable",
+ "it displays an enable button"
+ );
+ assert.ok(query(".disabled"), "it adds a 'disabled' CSS class");
+ },
+ }
+ );
+
+ componentTest(
+ "when a holiday is enabled, it displays a disable button and does not add a disabled CSS class",
+ {
+ template,
+
+ beforeEach() {
+ this.set("holiday", {
+ date: "2022-01-01",
+ name: "New Year's Day",
+ disabled: false,
+ });
+ this.set("region_code", "au");
+ },
+
+ async test(assert) {
+ assert.equal(
+ query("button").innerText,
+ "Disable",
+ "it displays a disable button"
+ );
+ assert.notOk(
+ query(".disabled"),
+ "it does not add a 'disabled' CSS class"
+ );
+ },
+ }
+ );
+ }
+);