diff --git a/test/integration/setting_test.rb b/test/integration/setting_test.rb
new file mode 100644
index 0000000..3a235fc
--- /dev/null
+++ b/test/integration/setting_test.rb
@@ -0,0 +1,126 @@
+require "test_helper"
+
+class Setting < ActionDispatch::IntegrationTest
+ include ::ConfigHistories::DaemonHaveSomeConfigHistories
+ include ::ConfigHistories::DaemonHadBeenStartedOnce
+
+ setup do
+ login_with(FactoryBot.build(:user))
+ stub_daemon
+ daemon.agent.config_write("GREAT CONFIG HERE")
+
+ visit("/daemon/setting")
+ end
+
+ test "show setting" do
+ assert do
+ page.has_css?('h1', text: I18n.t('fluentd.settings.show.page_title'))
+ end
+ assert do
+ page.has_link?(I18n.t('terms.edit'))
+ end
+ assert do
+ page.has_css?('pre', text: 'GREAT CONFIG HERE')
+ end
+ assert_equal(Settings.histories_count_in_preview + 1, all('.row tr').count) # links to hisotries#show + 1 table header
+ assert do
+ page.has_link?(I18n.t('fluentd.settings.show.link_to_histories'))
+ end
+ assert do
+ page.has_text?(I18n.t('fluentd.settings.running_backup.title'))
+ end
+ end
+
+ test "go to histories#index" do
+ click_link(I18n.t('fluentd.settings.show.link_to_histories'))
+
+ assert do
+ page.has_css?('h1', text: I18n.t('fluentd.settings.histories.index.page_title'))
+ end
+ end
+
+ test "go to histories#show" do
+ all('.row tr td a').first.click
+
+ assert do
+ page.has_css?('h1', text: I18n.t('fluentd.settings.histories.show.page_title'))
+ end
+ end
+
+ test "edit setting" do
+ click_link(I18n.t('terms.edit'))
+
+ assert do
+ page.has_css?('h1', text: I18n.t('fluentd.settings.edit.page_title'))
+ end
+ assert do
+ page.has_css?('p.text-danger', text: I18n.t('terms.notice_restart_for_config_edit', brand: 'fluentd'))
+ end
+
+ fill_in('config', with: 'YET ANOTHER CONFIG')
+
+ click_button(I18n.t('terms.update'))
+
+ assert_equal('/daemon/setting', current_path)
+ assert do
+ page.has_css?('pre', text: 'YET ANOTHER CONFIG')
+ end
+ end
+
+ sub_test_case "plain config" do
+ setup do
+ any_instance_of(Fluentd::Agent::TdAgent) do |object|
+ @conf = <<-'CONFIG'
+
+ @type forward
+
+ CONFIG
+ stub(object).dryrun(anything) { true }
+ daemon.agent.config_write(@conf)
+ click_link(I18n.t('terms.edit'))
+ end
+ end
+
+ test "configtest" do
+ click_button(I18n.t('terms.configtest'))
+ assert do
+ page.has_css?('.alert-success')
+ end
+ end
+
+ test "update & restart check" do
+ click_button(I18n.t('terms.update'))
+ # CodeMirror exchange \n -> \r\n
+ assert_equal(@conf, daemon.agent.config.gsub("\r\n", "\n"))
+ end
+ end
+
+ sub_test_case "embedded config" do
+ setup do
+ any_instance_of(Fluentd::Agent::TdAgent) do |object|
+ @conf = <<-'CONFIG'
+
+ type forward
+ id "foo#{Time.now.to_s}"
+
+ CONFIG
+ stub(object).dryrun(anything) { true }
+ daemon.agent.config_write(@conf)
+ click_link(I18n.t('terms.edit'))
+ end
+ end
+
+ test "configtest" do
+ click_button(I18n.t('terms.configtest'))
+ assert do
+ page.has_css?('.alert-success')
+ end
+ end
+
+ test "update & restart check" do
+ click_button(I18n.t('terms.update'))
+ # CodeMirror exchange \n -> \r\n
+ assert_equal(@conf, daemon.agent.config.gsub("\r\n", "\n"))
+ end
+ end
+end
diff --git a/test/integration/users_test.rb b/test/integration/users_test.rb
new file mode 100644
index 0000000..b244c3f
--- /dev/null
+++ b/test/integration/users_test.rb
@@ -0,0 +1,43 @@
+require "test_helper"
+
+class UsersTest < ActionDispatch::IntegrationTest
+ test "login required" do
+ login_required(user_path)
+ end
+
+ sub_test_case "edit" do
+ setup do
+ @user = FactoryBot.build(:user)
+ login_with(@user)
+ end
+
+ teardown do
+ # reset password to the default
+ FileUtils.rm_f(User::ENCRYPTED_PASSWORD_FILE)
+ end
+
+ sub_test_case "to change password" do
+ def update_password(current_password, password, password_confirmation)
+ visit user_path
+ fill_in 'user[current_password]', with: current_password
+
+ fill_in 'user[password]', with: password
+ fill_in 'user[password_confirmation]', with: password_confirmation
+ click_button I18n.t("terms.update_password")
+ end
+
+ test "when input valid new password/confirmation" do
+ update_password(@user.password, "newpassword", "newpassword")
+ page.has_css?(".alert-success")
+ assert_equal(@user.digest("newpassword"), @user.stored_digest)
+ end
+
+ test "when input invalid new password/confirmation" do
+ original_digest = @user.stored_digest
+ update_password(@user.password, "newpassword", "invalidpassword")
+ page.has_css?(".alert-danger")
+ assert_equal(original_digest, @user.stored_digest)
+ end
+ end
+ end
+end
diff --git a/test/support/config_histories.rb b/test/support/config_histories.rb
new file mode 100644
index 0000000..cda6d9b
--- /dev/null
+++ b/test/support/config_histories.rb
@@ -0,0 +1,68 @@
+require_relative "./stub_daemon"
+
+module ConfigHistories
+ module DaemonHaveSomeConfigHistories
+ extend ActiveSupport::Concern
+ include ::StubDaemon
+
+ included do
+ def daemon
+ @daemon ||= stub_daemon
+ end
+
+ setup do
+ config_contents = <<-CONFIG.strip_heredoc
+
+ @type forward
+ port 24224
+
+ CONFIG
+ new_config = <<-CONFIG
+
+ @type http
+ port 8899
+
+ CONFIG
+
+ three_hours_ago = Time.zone.now - 3.hours
+ Timecop.freeze(three_hours_ago)
+ FileUtils.rm_rf(daemon.agent.config_backup_dir)
+
+ 7.times do |i|
+ backup_time = three_hours_ago - (i+1).hours
+ FileUtils.touch(File.join(daemon.agent.config_backup_dir, "#{backup_time.strftime("%Y%m%d_%H%M%S")}.conf"))
+ end
+
+ Timecop.freeze(three_hours_ago + 1.hours)
+ daemon.agent.config_write(config_contents)
+
+ Timecop.freeze(three_hours_ago + 2.hours)
+ daemon.agent.config_write(new_config)
+
+ Timecop.freeze(three_hours_ago + 3.hours)
+ end
+
+ teardown do
+ FileUtils.rm_rf(daemon.agent.config_backup_dir)
+ Timecop.return
+ end
+ end
+ end
+
+ module DaemonHadBeenStartedOnce
+ extend ActiveSupport::Concern
+
+ included do
+ setup do
+ @backup_content = "Running backup file content"
+ File.open(daemon.agent.running_config_backup_file, "w") do |file|
+ file.write(@backup_content)
+ end
+ end
+
+ teardown do
+ FileUtils.rm_rf(daemon.agent.config_backup_dir)
+ end
+ end
+ end
+end
diff --git a/test/support/login_required.rb b/test/support/login_required.rb
new file mode 100644
index 0000000..0a598ce
--- /dev/null
+++ b/test/support/login_required.rb
@@ -0,0 +1,8 @@
+module LoginRequired
+ def login_required(url)
+ visit(url)
+ assert_equal(new_sessions_path, current_path)
+ end
+end
+
+ActionDispatch::IntegrationTest.include(LoginRequired)