diff --git a/app/assets/javascripts/app/controllers/calendar.coffee b/app/assets/javascripts/app/controllers/calendar.coffee
index 30ab707f2..0b7007afa 100644
--- a/app/assets/javascripts/app/controllers/calendar.coffee
+++ b/app/assets/javascripts/app/controllers/calendar.coffee
@@ -12,15 +12,18 @@ class Index extends App.ControllerSubContent
super
@subscribeId = App.Calendar.subscribe(@render)
- callback = (data) =>
- App.Config.set('ical_feeds', data.ical_feeds)
- App.Config.set('timezones', data.timezones)
- @stopLoading()
- @render()
@startLoading()
- App.Calendar.fetchFull(
- callback
- clear: true
+ @ajax(
+ id: 'calendar_index'
+ type: 'GET'
+ url: @apiPath + '/calendars_init'
+ processData: true
+ success: (data, status, xhr) =>
+ App.Config.set('ical_feeds', data.ical_feeds)
+ App.Config.set('timezones', data.timezones)
+ App.Collection.loadAssets(data.assets)
+ @stopLoading()
+ @render()
)
render: =>
@@ -59,7 +62,7 @@ class Index extends App.ControllerSubContent
if !_.isEmpty(calendars)
showDescription = true
else
- description = marked(App[ @genericObject ].description)
+ description = marked(App.Calendar.description)
@html App.view('calendar/index')(
calendars: calendars
diff --git a/app/assets/javascripts/app/models/calendar.coffee b/app/assets/javascripts/app/models/calendar.coffee
index 771bab8cf..29c10cf47 100644
--- a/app/assets/javascripts/app/models/calendar.coffee
+++ b/app/assets/javascripts/app/models/calendar.coffee
@@ -5,7 +5,7 @@ class App.Calendar extends App.Model
@configure_attributes = [
{ name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, null: false },
- { name: 'timezone', display: 'Time zone', tag: 'timezone', null: false }
+ { name: 'timezone', display: 'Time zone', tag: 'timezone', null: false }
{ name: 'business_hours', display: 'Business Hours', tag: 'business_hours', null: true }
{ name: 'ical_url', display: 'Holidays iCalendar Feed', tag: 'ical_feed', placeholder: 'http://example.com/public_holidays.ical', null: true }
{ name: 'public_holidays',display: 'Holidays', tag: 'holiday_selector', null: true }
diff --git a/app/assets/javascripts/app/views/generic/searchable_select.jst.eco b/app/assets/javascripts/app/views/generic/searchable_select.jst.eco
index 70139147e..ea66976d6 100644
--- a/app/assets/javascripts/app/views/generic/searchable_select.jst.eco
+++ b/app/assets/javascripts/app/views/generic/searchable_select.jst.eco
@@ -1,7 +1,7 @@
id="<%= @attribute.id %>"<% end %>
name="<%= @attribute.name %>"
<%= @attribute.required %>
<%= @attribute.autofocus %>
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index 75ca96bb3..9cff88a63 100644
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -3,26 +3,28 @@
class CalendarsController < ApplicationController
prepend_before_action { authentication_check(permission: 'admin.calendar') }
- def index
-
- # calendars
+ def init
assets = {}
- calendar_ids = []
+ record_ids = []
Calendar.all.order(:name, :created_at).each do |calendar|
- calendar_ids.push calendar.id
+ record_ids.push calendar.id
assets = calendar.assets(assets)
end
ical_feeds = Calendar.ical_feeds
timezones = Calendar.timezones
render json: {
- calendar_ids: calendar_ids,
+ record_ids: record_ids,
ical_feeds: ical_feeds,
timezones: timezones,
assets: assets,
}, status: :ok
end
+ def index
+ model_index_render(Calendar, params)
+ end
+
def show
model_show_render(Calendar, params)
end
diff --git a/config/routes/calendar.rb b/config/routes/calendar.rb
index b0d2a39b3..d83201939 100644
--- a/config/routes/calendar.rb
+++ b/config/routes/calendar.rb
@@ -2,6 +2,7 @@ Zammad::Application.routes.draw do
api_path = Rails.configuration.api_path
# calendars
+ match api_path + '/calendars_init', to: 'calendars#init', via: :get
match api_path + '/calendars', to: 'calendars#index', via: :get
match api_path + '/calendars/:id', to: 'calendars#show', via: :get
match api_path + '/calendars', to: 'calendars#create', via: :post
diff --git a/script/build/test_slice_tests.sh b/script/build/test_slice_tests.sh
index 5dcfd5e55..db555d20d 100755
--- a/script/build/test_slice_tests.sh
+++ b/script/build/test_slice_tests.sh
@@ -15,6 +15,7 @@ if [ "$LEVEL" == '1' ]; then
# test/browser/aac_basic_richtext_test.rb
rm test/browser/abb_one_group_test.rb
rm test/browser/admin_channel_email_test.rb
+ rm test/browser/admin_calendar_sla_test.rb
rm test/browser/admin_object_manager_test.rb
rm test/browser/admin_object_manager_tree_select_test.rb
rm test/browser/admin_overview_test.rb
@@ -82,6 +83,7 @@ elif [ "$LEVEL" == '2' ]; then
rm test/browser/aac_basic_richtext_test.rb
# test/browser/abb_one_group_test.rb
rm test/browser/admin_channel_email_test.rb
+ rm test/browser/admin_calendar_sla_test.rb
rm test/browser/admin_object_manager_test.rb
rm test/browser/admin_object_manager_tree_select_test.rb
rm test/browser/admin_overview_test.rb
@@ -149,6 +151,7 @@ elif [ "$LEVEL" == '3' ]; then
rm test/browser/aac_basic_richtext_test.rb
# test/browser/abb_one_group_test.rb
rm test/browser/admin_channel_email_test.rb
+ rm test/browser/admin_calendar_sla_test.rb
rm test/browser/admin_object_manager_test.rb
rm test/browser/admin_object_manager_tree_select_test.rb
rm test/browser/admin_overview_test.rb
@@ -216,6 +219,7 @@ elif [ "$LEVEL" == '4' ]; then
rm test/browser/aac_basic_richtext_test.rb
# test/browser/abb_one_group_test.rb
rm test/browser/admin_channel_email_test.rb
+ rm test/browser/admin_calendar_sla_test.rb
rm test/browser/admin_object_manager_test.rb
rm test/browser/admin_object_manager_tree_select_test.rb
rm test/browser/admin_overview_test.rb
@@ -282,6 +286,7 @@ elif [ "$LEVEL" == '5' ]; then
rm test/browser/aac_basic_richtext_test.rb
# test/browser/abb_one_group_test.rb
# test/browser/admin_channel_email_test.rb
+ # test/browser/admin_calendar_sla_test.rb
# test/browser/admin_object_manager_test.rb
# test/browser/admin_object_manager_tree_select_test.rb
# test/browser/admin_overview_test.rb
@@ -351,6 +356,7 @@ elif [ "$LEVEL" == '6' ]; then
rm test/browser/aac_basic_richtext_test.rb
rm test/browser/abb_one_group_test.rb
rm test/browser/admin_channel_email_test.rb
+ rm test/browser/admin_calendar_sla_test.rb
rm test/browser/admin_object_manager_test.rb
rm test/browser/admin_object_manager_tree_select_test.rb
rm test/browser/admin_overview_test.rb
diff --git a/test/browser/admin_calendar_sla_test.rb b/test/browser/admin_calendar_sla_test.rb
new file mode 100644
index 000000000..067bb5010
--- /dev/null
+++ b/test/browser/admin_calendar_sla_test.rb
@@ -0,0 +1,84 @@
+
+require 'browser_test_helper'
+
+class AdminCalendarSlaTest < TestCase
+ def test_calendar
+ @browser = browser_instance
+ login(
+ username: 'master@example.com',
+ password: 'test',
+ url: browser_url,
+ )
+ tasks_close_all()
+
+ calendar_name = "ZZZ some calendar #{rand(99_999_999)}"
+ sla_name = "ZZZ some sla #{rand(99_999_999)}"
+ timezone = 'Europe/Berlin'
+ timezone_verify = 'Europe/Berlin (GMT+2)'
+ calendar_create(
+ data: {
+ name: calendar_name,
+ timezone: timezone,
+ }
+ )
+
+ # got to maintanance
+ click(css: '[href="#manage"]')
+ click(css: '[href="#system/maintenance"]')
+ watch_for(
+ css: '.content.active',
+ value: 'Enable or disable the maintenance mode',
+ timeout: 4,
+ )
+
+ # go back
+ click(css: '[href="#manage"]')
+ click(css: '[href="#manage/calendars"]')
+ watch_for(
+ css: '.content.active',
+ value: calendar_name,
+ timeout: 4,
+ )
+
+ logout()
+
+ login(
+ username: 'master@example.com',
+ password: 'test',
+ )
+
+ # check if admin exists
+ click(css: '[href="#manage"]')
+ click(css: '[href="#manage/calendars"]')
+ watch_for(
+ css: '.content.active',
+ value: calendar_name,
+ timeout: 4,
+ )
+
+ #@browser.execute_script('$(\'.content.active table tr td:contains(" ' + data[:name] + '")\').first().click()')
+ @browser.execute_script('$(\'.content.active .main .js-edit\').last().click()')
+
+ modal_ready(browser: @browser)
+ watch_for(
+ css: '.content.active .modal input[name=name]',
+ value: calendar_name,
+ timeout: 4,
+ )
+ watch_for(
+ css: '.content.active .modal input.js-input',
+ value: Regexp.quote(timezone_verify),
+ timeout: 4,
+ )
+ modal_close()
+
+ sla_create(
+ data: {
+ name: sla_name,
+ calendar: "#{calendar_name} - #{timezone}",
+ first_response_time_in_text: 61
+ },
+ )
+
+ end
+end
diff --git a/test/browser_test_helper.rb b/test/browser_test_helper.rb
index 8ba75c7ea..d0cb856f7 100644
--- a/test/browser_test_helper.rb
+++ b/test/browser_test_helper.rb
@@ -487,6 +487,26 @@ class TestCase < Test::Unit::TestCase
screenshot(browser: instance, comment: 'scroll_to_after')
end
+=begin
+
+ modal_close(
+ browser: browser1,
+ )
+
+=end
+
+ def modal_close(params = {})
+ switch_window_focus(params)
+ log('modal_close', params)
+
+ instance = params[:browser] || @browser
+
+ element = instance.find_elements(css: '.modal .js-close')[0]
+ raise "No such modal to close #{params.inspect}" if !element
+
+ element.click
+ end
+
=begin
modal_ready(
@@ -2717,12 +2737,72 @@ wait untill text in selector disabppears
assert(true, 'user created')
end
+=begin
+
+ calendar_create(
+ browser: browser2,
+ data: {
+ name: 'some calendar' + random,
+ first_response_time_in_text: 61
+ },
+ )
+
+=end
+
+ def calendar_create(params = {})
+ switch_window_focus(params)
+ log('calendar_create', params)
+
+ instance = params[:browser] || @browser
+ data = params[:data]
+
+ click(
+ browser: instance,
+ css: 'a[href="#manage"]',
+ mute_log: true,
+ )
+ click(
+ browser: instance,
+ css: '.content.active a[href="#manage/calendars"]',
+ mute_log: true,
+ )
+ sleep 4
+ click(
+ browser: instance,
+ css: '.content.active a.js-new',
+ mute_log: true,
+ )
+ modal_ready(browser: instance)
+ element = instance.find_elements(css: '.content.active .modal input[name=name]')[0]
+ element.clear
+ element.send_keys(data[:name])
+ element = instance.find_elements(css: '.content.active .modal .js-input')[0]
+ element.clear
+ element.send_keys(data[:timezone])
+ element.send_keys(:enter)
+ instance.find_elements(css: '.modal button.js-submit')[0].click
+ modal_disappear(browser: instance)
+ 7.times do
+ element = instance.find_elements(css: 'body')[0]
+ text = element.text
+ if text.match?(/#{Regexp.quote(data[:name])}/)
+ assert(true, 'calendar created')
+ sleep 1
+ return true
+ end
+ sleep 1
+ end
+ screenshot(browser: instance, comment: 'calendar_create_failed')
+ raise 'calendar creation failed'
+ end
+
=begin
sla_create(
browser: browser2,
data: {
name: 'some sla' + random,
+ calendar: 'some calendar name',
first_response_time_in_text: 61
},
)
@@ -2755,6 +2835,11 @@ wait untill text in selector disabppears
element = instance.find_elements(css: '.modal input[name=name]')[0]
element.clear
element.send_keys(data[:name])
+ if data[:calendar].present?
+ element = instance.find_elements(css: '.modal select[name="calendar_id"]')[0]
+ dropdown = Selenium::WebDriver::Support::Select.new(element)
+ dropdown.select_by(:text, data[:calendar])
+ end
element = instance.find_elements(css: '.modal input[name=first_response_time_in_text]')[0]
element.clear
element.send_keys(data[:first_response_time_in_text])
diff --git a/test/controllers/calendar_controller_test.rb b/test/controllers/calendar_controller_test.rb
new file mode 100644
index 000000000..68731739d
--- /dev/null
+++ b/test/controllers/calendar_controller_test.rb
@@ -0,0 +1,90 @@
+
+require 'test_helper'
+
+class CalendarControllerTest < ActionDispatch::IntegrationTest
+ setup do
+
+ # set accept header
+ @headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' }
+
+ # create agent
+ roles = Role.where(name: %w[Admin Agent])
+ groups = Group.all
+
+ UserInfo.current_user_id = 1
+ @admin = User.create_or_update(
+ login: 'calendar-admin',
+ firstname: 'Packages',
+ lastname: 'Admin',
+ email: 'calendar-admin@example.com',
+ password: 'adminpw',
+ active: true,
+ roles: roles,
+ groups: groups,
+ )
+
+ end
+
+ test '01 calendar index with nobody' do
+
+ get '/api/v1/calendars', params: {}, headers: @headers
+ assert_response(401)
+
+ result = JSON.parse(@response.body)
+ assert_equal(Hash, result.class)
+ assert_equal('authentication failed', result['error'])
+
+ get '/api/v1/calendars_init', params: {}, headers: @headers
+ assert_response(401)
+
+ result = JSON.parse(@response.body)
+ assert_equal(Hash, result.class)
+ assert_equal('authentication failed', result['error'])
+ end
+
+ test '02 calendar index with admin' do
+
+ credentials = ActionController::HttpAuthentication::Basic.encode_credentials('calendar-admin@example.com', 'adminpw')
+
+ # index
+ get '/api/v1/calendars', params: {}, headers: @headers.merge('Authorization' => credentials)
+ assert_response(200)
+ result = JSON.parse(@response.body)
+ assert_equal(Array, result.class)
+ assert(result)
+ assert_equal(1, result.count)
+
+ get '/api/v1/calendars?expand=true', params: {}, headers: @headers.merge('Authorization' => credentials)
+ assert_response(200)
+ result = JSON.parse(@response.body)
+ assert_equal(Array, result.class)
+ assert(result)
+ assert_equal(1, result.count)
+
+ get '/api/v1/calendars?full=true', params: {}, headers: @headers.merge('Authorization' => credentials)
+ assert_response(200)
+ result = JSON.parse(@response.body)
+ assert_equal(Hash, result.class)
+ assert(result)
+ assert(result['record_ids'])
+ assert_equal(1, result['record_ids'].count)
+ assert(result['assets'])
+ assert(result['assets'].present?)
+
+ # index
+ get '/api/v1/calendars_init', params: {}, headers: @headers.merge('Authorization' => credentials)
+ assert_response(200)
+ result = JSON.parse(@response.body)
+ assert_equal(Hash, result.class)
+ assert(result['record_ids'])
+ assert(result['ical_feeds'])
+ assert_equal('Denmark', result['ical_feeds']['http://www.google.com/calendar/ical/da.danish%23holiday%40group.v.calendar.google.com/public/basic.ics'])
+ assert_equal('Austria', result['ical_feeds']['http://www.google.com/calendar/ical/de.austrian%23holiday%40group.v.calendar.google.com/public/basic.ics'])
+ assert(result['timezones'])
+ assert_equal(2, result['timezones']['Africa/Johannesburg'])
+ assert_equal(-8, result['timezones']['America/Sitka'])
+ assert(result['assets'])
+
+ end
+
+end
diff --git a/test/controllers/sla_controller_test.rb b/test/controllers/sla_controller_test.rb
new file mode 100644
index 000000000..b5d28ea31
--- /dev/null
+++ b/test/controllers/sla_controller_test.rb
@@ -0,0 +1,70 @@
+
+require 'test_helper'
+
+class SlaControllerTest < ActionDispatch::IntegrationTest
+ setup do
+
+ # set accept header
+ @headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' }
+
+ # create agent
+ roles = Role.where(name: %w[Admin Agent])
+ groups = Group.all
+
+ UserInfo.current_user_id = 1
+ @admin = User.create_or_update(
+ login: 'sla-admin',
+ firstname: 'Packages',
+ lastname: 'Admin',
+ email: 'sla-admin@example.com',
+ password: 'adminpw',
+ active: true,
+ roles: roles,
+ groups: groups,
+ )
+
+ end
+
+ test '01 sla index with nobody' do
+
+ get '/api/v1/slas', params: {}, headers: @headers
+ assert_response(401)
+
+ result = JSON.parse(@response.body)
+ assert_equal(Hash, result.class)
+ assert_equal('authentication failed', result['error'])
+
+ end
+
+ test '02 sla index with admin' do
+
+ credentials = ActionController::HttpAuthentication::Basic.encode_credentials('sla-admin@example.com', 'adminpw')
+
+ get '/api/v1/slas', params: {}, headers: @headers.merge('Authorization' => credentials)
+ assert_response(200)
+ result = JSON.parse(@response.body)
+ assert_equal(Array, result.class)
+ assert(result)
+ assert_equal(0, result.count)
+
+ get '/api/v1/slas?expand=true', params: {}, headers: @headers.merge('Authorization' => credentials)
+ assert_response(200)
+ result = JSON.parse(@response.body)
+ assert_equal(Array, result.class)
+ assert(result)
+ assert_equal(0, result.count)
+
+ get '/api/v1/slas?full=true', params: {}, headers: @headers.merge('Authorization' => credentials)
+ assert_response(200)
+ result = JSON.parse(@response.body)
+ assert_equal(Hash, result.class)
+ assert(result)
+ assert(result['record_ids'])
+ assert(result['record_ids'].blank?)
+ assert(result['assets'])
+ assert(result['assets']['Calendar'].present?)
+ assert(result['assets'].present?)
+
+ end
+
+end