Merge pull request 'Complete admin pages for service settings' (#104) from feature/admin_user_service_settings into master
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #104 Reviewed-by: galfert <garret.alfert@gmail.com>
This commit is contained in:
commit
90680368fb
@ -1,10 +1,16 @@
|
|||||||
LDAP_HOST=localhost
|
LDAP_HOST=localhost
|
||||||
LDAP_PORT=389
|
LDAP_PORT=389
|
||||||
LDAP_ADMIN_PASSWORD=passthebutter
|
LDAP_ADMIN_PASSWORD=passthebutter
|
||||||
LDAP_SUFFIX="dc=kosmos,dc=org"
|
LDAP_SUFFIX='dc=kosmos,dc=org'
|
||||||
|
|
||||||
WEBHOOKS_ALLOWED_IPS='10.1.1.163'
|
WEBHOOKS_ALLOWED_IPS='10.1.1.163'
|
||||||
|
|
||||||
|
DISCOURSE_PUBLIC_URL='https://community.kosmos.org'
|
||||||
|
GITEA_PUBLIC_URL='https://gitea.kosmos.org'
|
||||||
|
MASTODON_PUBLIC_URL='https://kosmos.social'
|
||||||
|
MEDIAWIKI_PUBLIC_URL='https://wiki.kosmos.org'
|
||||||
|
|
||||||
|
EJABBERD_ADMIN_URL='https://xmpp.kosmos.org/admin'
|
||||||
EJABBERD_API_URL='https://xmpp.kosmos.org/api'
|
EJABBERD_API_URL='https://xmpp.kosmos.org/api'
|
||||||
|
|
||||||
BTCPAY_API_URL='http://localhost:23001/api/v1'
|
BTCPAY_API_URL='http://localhost:23001/api/v1'
|
||||||
@ -18,3 +24,4 @@ LNDHUB_PG_PORT=5432
|
|||||||
LNDHUB_PG_DATABASE=lndhub
|
LNDHUB_PG_DATABASE=lndhub
|
||||||
LNDHUB_PG_USERNAME=lndhub
|
LNDHUB_PG_USERNAME=lndhub
|
||||||
LNDHUB_PG_PASSWORD=''
|
LNDHUB_PG_PASSWORD=''
|
||||||
|
|
||||||
|
13
app/components/form_elements/fieldset_component.html.erb
Normal file
13
app/components/form_elements/fieldset_component.html.erb
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<%= tag.public_send(@tag, class: "mb-6 last:mb-0") do %>
|
||||||
|
<label class="block">
|
||||||
|
<p class="font-bold <%= @descripton.present? ? "mb-1" : "mb-2" %>">
|
||||||
|
<%= @title %>
|
||||||
|
</p>
|
||||||
|
<% if @descripton.present? %>
|
||||||
|
<p class="text-gray-500">
|
||||||
|
<%= @descripton %>
|
||||||
|
</p>
|
||||||
|
<% end %>
|
||||||
|
<%= content %>
|
||||||
|
</label>
|
||||||
|
<% end %>
|
11
app/components/form_elements/fieldset_component.rb
Normal file
11
app/components/form_elements/fieldset_component.rb
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module FormElements
|
||||||
|
class FieldsetComponent < ViewComponent::Base
|
||||||
|
def initialize(tag: "li", title:, description: nil)
|
||||||
|
@tag = tag
|
||||||
|
@title = title
|
||||||
|
@descripton = description
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,26 @@
|
|||||||
|
<%= tag.public_send @tag, class: "flex items-center justify-between mb-6 last:mb-0",
|
||||||
|
data: @form.present? ? {
|
||||||
|
controller: "settings--toggle",
|
||||||
|
:'settings--toggle-switch-enabled-value' => @enabled.to_s
|
||||||
|
} : nil do %>
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<label class="font-bold mb-1"><%= @title %></label>
|
||||||
|
<p class="text-gray-500"><%= @descripton %></p>
|
||||||
|
</div>
|
||||||
|
<div class="relative ml-4 inline-flex flex-shrink-0">
|
||||||
|
<%= render FormElements::ToggleComponent.new(
|
||||||
|
enabled: @enabled,
|
||||||
|
input_enabled: @input_enabled,
|
||||||
|
class_names: @form.present? ? "hidden" : nil,
|
||||||
|
data: {
|
||||||
|
:'settings--toggle-target' => "button",
|
||||||
|
action: "settings--toggle#toggleSwitch"
|
||||||
|
}) %>
|
||||||
|
<% if @form.present? %>
|
||||||
|
<%= @form.check_box @attribute, {
|
||||||
|
checked: @enabled,
|
||||||
|
data: { :'settings--toggle-target' => "checkbox" }
|
||||||
|
}, "true", "false" %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
17
app/components/form_elements/fieldset_toggle_component.rb
Normal file
17
app/components/form_elements/fieldset_toggle_component.rb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module FormElements
|
||||||
|
class FieldsetToggleComponent < ViewComponent::Base
|
||||||
|
def initialize(form: nil, attribute: nil, tag: "li", enabled: false,
|
||||||
|
input_enabled: true, title:, description:)
|
||||||
|
@form = form
|
||||||
|
@attribute = attribute
|
||||||
|
@tag = tag
|
||||||
|
@enabled = enabled
|
||||||
|
@input_enabled = input_enabled
|
||||||
|
@title = title
|
||||||
|
@descripton = description
|
||||||
|
@button_text = @enabled ? "Switch off" : "Switch on"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
15
app/components/form_elements/toggle_component.html.erb
Normal file
15
app/components/form_elements/toggle_component.html.erb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<%= button_tag type: "button", name: "toggle", data: @data,
|
||||||
|
role: "switch", aria: { checked: @enabled.to_s },
|
||||||
|
disabled: !@input_enabled,
|
||||||
|
class: "#{ @enabled ? 'bg-blue-600' : 'bg-gray-200' }
|
||||||
|
#{ @class_names.present? ? @class_names : '' }
|
||||||
|
relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer
|
||||||
|
rounded-full border-2 border-transparent transition-colors
|
||||||
|
duration-200 ease-in-out focus:outline-none focus:ring-2
|
||||||
|
focus:ring-blue-600 focus:ring-offset-2" do %>
|
||||||
|
<span class="sr-only"><%= @button_text %></span>
|
||||||
|
<span aria-hidden="true" data-settings--toggle-target="switch"
|
||||||
|
class="<%= @enabled ? 'translate-x-5' : 'translate-x-0' %>
|
||||||
|
pointer-events-none inline-block h-5 w-5 transform rounded-full
|
||||||
|
bg-white shadow ring-0 transition duration-200 ease-in-out"></span>
|
||||||
|
<% end %>
|
12
app/components/form_elements/toggle_component.rb
Normal file
12
app/components/form_elements/toggle_component.rb
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module FormElements
|
||||||
|
class ToggleComponent < ViewComponent::Base
|
||||||
|
def initialize(enabled:, input_enabled: true, data: nil, class_names: nil)
|
||||||
|
@enabled = !!enabled
|
||||||
|
@input_enabled = input_enabled
|
||||||
|
@data = data
|
||||||
|
@class_names = class_names
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -1,8 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SidenavLinkComponent < ViewComponent::Base
|
class SidenavLinkComponent < ViewComponent::Base
|
||||||
def initialize(name:, path:, icon:, active: false, disabled: false)
|
def initialize(name:, level: 1, path:, icon:, active: false, disabled: false)
|
||||||
@name = name
|
@name = name
|
||||||
|
@level = level
|
||||||
@path = path
|
@path = path
|
||||||
@icon = icon
|
@icon = icon
|
||||||
@active = active
|
@active = active
|
||||||
@ -12,12 +13,15 @@ class SidenavLinkComponent < ViewComponent::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def class_names_link(path)
|
def class_names_link(path)
|
||||||
|
px = @level == 1 ? "px-4" : "pl-8 pr-4"
|
||||||
|
base = "#{px} py-2 group border-l-4 flex items-center text-base font-medium"
|
||||||
|
|
||||||
if @active
|
if @active
|
||||||
"bg-teal-50 border-teal-500 text-teal-700 hover:bg-teal-50 hover:text-teal-700 group border-l-4 px-4 py-2 flex items-center text-base font-medium"
|
"#{base} bg-teal-50 border-teal-500 text-teal-700 hover:bg-teal-50 hover:text-teal-700"
|
||||||
elsif @disabled
|
elsif @disabled
|
||||||
"border-transparent text-gray-400 hover:bg-gray-50 group border-l-4 px-4 py-2 flex items-center text-base font-medium"
|
"#{base} border-transparent text-gray-400 hover:bg-gray-50"
|
||||||
else
|
else
|
||||||
"border-transparent text-gray-900 hover:bg-gray-50 hover:text-gray-900 group border-l-4 px-4 py-2 flex items-center text-base font-medium"
|
"#{base} border-transparent text-gray-900 hover:bg-gray-50 hover:text-gray-900"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,38 +1,12 @@
|
|||||||
class Admin::Settings::RegistrationsController < Admin::SettingsController
|
class Admin::Settings::RegistrationsController < Admin::SettingsController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@errors = ActiveModel::Errors.new(Setting.new)
|
update_settings
|
||||||
|
|
||||||
setting_params.keys.each do |key|
|
|
||||||
next if setting_params[key].nil?
|
|
||||||
|
|
||||||
setting = Setting.new(var: key)
|
|
||||||
setting.value = setting_params[key].strip
|
|
||||||
unless setting.valid?
|
|
||||||
@errors.merge!(setting.errors)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if @errors.any?
|
|
||||||
render :index
|
|
||||||
end
|
|
||||||
|
|
||||||
setting_params.keys.each do |key|
|
|
||||||
Setting.send("#{key}=", setting_params[key].strip) unless setting_params[key].nil?
|
|
||||||
end
|
|
||||||
|
|
||||||
redirect_to admin_settings_registrations_path, flash: {
|
redirect_to admin_settings_registrations_path, flash: {
|
||||||
success: "Settings saved"
|
success: "Settings saved"
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def setting_params
|
|
||||||
params.require(:setting).permit(:reserved_usernames)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1,9 +1,19 @@
|
|||||||
class Admin::Settings::ServicesController < Admin::SettingsController
|
class Admin::Settings::ServicesController < Admin::SettingsController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
@service = params[:s]
|
||||||
|
|
||||||
|
if @service.blank?
|
||||||
|
redirect_to admin_settings_services_path(params: { s: "discourse" })
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def create
|
||||||
end
|
service = params.require(:service)
|
||||||
|
|
||||||
|
update_settings
|
||||||
|
|
||||||
|
redirect_to admin_settings_services_path(params: { s: service }), flash: {
|
||||||
|
success: "Settings saved"
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -4,9 +4,37 @@ class Admin::SettingsController < Admin::BaseController
|
|||||||
def index
|
def index
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_settings
|
||||||
|
@errors = ActiveModel::Errors.new(Setting.new)
|
||||||
|
changed_keys = []
|
||||||
|
|
||||||
|
setting_params.keys.each do |key|
|
||||||
|
next if setting_params[key].nil? ||
|
||||||
|
(Setting.send(key).to_s == setting_params[key].strip)
|
||||||
|
changed_keys.push(key)
|
||||||
|
setting = Setting.new(var: key)
|
||||||
|
setting.value = setting_params[key].strip
|
||||||
|
unless setting.valid?
|
||||||
|
@errors.merge!(setting.errors)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if @errors.any?
|
||||||
|
render :index and return
|
||||||
|
end
|
||||||
|
|
||||||
|
changed_keys.each do |key|
|
||||||
|
Setting.send("#{key}=", setting_params[key].strip)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_current_section
|
def set_current_section
|
||||||
@current_section = :settings
|
@current_section = :settings
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def setting_params
|
||||||
|
params.require(:setting).permit(Setting.editable_keys.map(&:to_sym))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
30
app/javascript/controllers/settings/toggle_controller.js
Normal file
30
app/javascript/controllers/settings/toggle_controller.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { Controller } from "@hotwired/stimulus"
|
||||||
|
|
||||||
|
export default class extends Controller {
|
||||||
|
static targets = [ "button", "switch", "checkbox" ]
|
||||||
|
static values = { switchEnabled: Boolean }
|
||||||
|
|
||||||
|
connect () {
|
||||||
|
this.buttonTarget.classList.remove("hidden")
|
||||||
|
this.checkboxTarget.classList.add("hidden")
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleSwitch () {
|
||||||
|
this.switchEnabledValue = !this.switchEnabledValue
|
||||||
|
this.checkboxTarget.checked = this.switchEnabledValue
|
||||||
|
|
||||||
|
if (this.switchEnabledValue) {
|
||||||
|
this.buttonTarget.setAttribute("aria-checked", "true");
|
||||||
|
this.buttonTarget.classList.remove("bg-gray-200")
|
||||||
|
this.buttonTarget.classList.add("bg-blue-600")
|
||||||
|
this.switchTarget.classList.remove("translate-x-0")
|
||||||
|
this.switchTarget.classList.add("translate-x-5")
|
||||||
|
} else {
|
||||||
|
this.buttonTarget.setAttribute("aria-checked", "false");
|
||||||
|
this.buttonTarget.classList.remove("bg-blue-600")
|
||||||
|
this.buttonTarget.classList.add("bg-gray-200")
|
||||||
|
this.switchTarget.classList.remove("translate-x-5")
|
||||||
|
this.switchTarget.classList.add("translate-x-0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,12 +7,12 @@ class XmppExchangeContactsJob < ApplicationJob
|
|||||||
ejabberd.add_rosteritem({
|
ejabberd.add_rosteritem({
|
||||||
"localuser": username, "localhost": domain,
|
"localuser": username, "localhost": domain,
|
||||||
"user": inviter.cn, "host": inviter.ou,
|
"user": inviter.cn, "host": inviter.ou,
|
||||||
"nick": inviter.cn, "group": "Friends", "subs": "both"
|
"nick": inviter.cn, "group": Setting.ejabberd_buddy_roster, "subs": "both"
|
||||||
})
|
})
|
||||||
ejabberd.add_rosteritem({
|
ejabberd.add_rosteritem({
|
||||||
"localuser": inviter.cn, "localhost": inviter.ou,
|
"localuser": inviter.cn, "localhost": inviter.ou,
|
||||||
"user": username, "host": domain,
|
"user": username, "host": domain,
|
||||||
"nick": username, "group": "Friends", "subs": "both"
|
"nick": username, "group": Setting.ejabberd_buddy_roster, "subs": "both"
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -10,19 +10,84 @@ class Setting < RailsSettings::Base
|
|||||||
account accounts donations mail webmaster support
|
account accounts donations mail webmaster support
|
||||||
]
|
]
|
||||||
|
|
||||||
|
#
|
||||||
|
# Discourse
|
||||||
|
#
|
||||||
|
|
||||||
|
field :discourse_public_url, type: :string, readonly: true,
|
||||||
|
default: ENV["DISCOURSE_PUBLIC_URL"].presence
|
||||||
|
|
||||||
|
field :discourse_enabled, type: :boolean,
|
||||||
|
default: (ENV["DISCOURSE_PUBLIC_URL"].present?.to_s || false)
|
||||||
|
|
||||||
|
#
|
||||||
|
# ejabberd
|
||||||
|
#
|
||||||
|
|
||||||
|
field :ejabberd_enabled, type: :boolean,
|
||||||
|
default: (ENV["EJABBERD_API_URL"].present?.to_s || false)
|
||||||
|
|
||||||
|
field :ejabberd_api_url, type: :string, readonly: true,
|
||||||
|
default: ENV["EJABBERD_API_URL"].presence
|
||||||
|
|
||||||
|
field :ejabberd_admin_url, type: :string, readonly: true,
|
||||||
|
default: ENV["EJABBERD_ADMIN_URL"].presence
|
||||||
|
|
||||||
|
field :ejabberd_buddy_roster, type: :string,
|
||||||
|
default: "Buddies"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gitea
|
||||||
|
#
|
||||||
|
|
||||||
|
field :gitea_public_url, type: :string, readonly: true,
|
||||||
|
default: ENV["GITEA_PUBLIC_URL"].presence
|
||||||
|
|
||||||
|
field :gitea_enabled, type: :boolean,
|
||||||
|
default: (ENV["GITEA_PUBLIC_URL"].present?.to_s || false)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Lightning Network
|
# Lightning Network
|
||||||
#
|
#
|
||||||
|
|
||||||
|
field :lndhub_api_url, type: :string, readonly: true,
|
||||||
|
default: ENV["LNDHUB_API_URL"].presence
|
||||||
|
|
||||||
field :lndhub_enabled, type: :boolean,
|
field :lndhub_enabled, type: :boolean,
|
||||||
default: (ENV["LNDHUB_API_URL"].present?.to_s || false)
|
default: (ENV["LNDHUB_API_URL"].present?.to_s || false)
|
||||||
|
|
||||||
field :lndhub_admin_enabled, type: :boolean,
|
field :lndhub_admin_enabled, type: :boolean,
|
||||||
default: (ENV["LNDHUB_ADMIN_UI"] || false)
|
default: (ENV["LNDHUB_ADMIN_UI"] || false)
|
||||||
|
|
||||||
field :lndhub_public_key, type: :string,
|
field :lndhub_public_key, type: :string, readonly: true,
|
||||||
default: (ENV["LNDHUB_PUBLIC_KEY"] || "")
|
default: (ENV["LNDHUB_PUBLIC_KEY"] || "")
|
||||||
|
|
||||||
field :lndhub_keysend_enabled, type: :boolean,
|
field :lndhub_keysend_enabled, type: :boolean,
|
||||||
default: -> { self.lndhub_public_key.present?.to_s || false }
|
default: -> { self.lndhub_public_key.present?.to_s || false }
|
||||||
|
|
||||||
|
#
|
||||||
|
# Mastodon
|
||||||
|
#
|
||||||
|
|
||||||
|
field :mastodon_public_url, type: :string, readonly: true,
|
||||||
|
default: ENV["MASTODON_PUBLIC_URL"].presence
|
||||||
|
|
||||||
|
field :mastodon_enabled, type: :boolean,
|
||||||
|
default: (ENV["MASTODON_PUBLIC_URL"].present?.to_s || false)
|
||||||
|
|
||||||
|
#
|
||||||
|
# MediaWiki
|
||||||
|
#
|
||||||
|
|
||||||
|
field :mediawiki_public_url, type: :string, readonly: true,
|
||||||
|
default: ENV["MEDIAWIKI_PUBLIC_URL"].presence
|
||||||
|
|
||||||
|
field :mediawiki_enabled, type: :boolean,
|
||||||
|
default: (ENV["MEDIAWIKI_PUBLIC_URL"].present?.to_s || false)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Nostr
|
||||||
|
#
|
||||||
|
|
||||||
|
field :nostr_enabled, type: :boolean, default: true
|
||||||
end
|
end
|
||||||
|
@ -53,7 +53,7 @@ class User < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def devise_after_confirmation
|
def devise_after_confirmation
|
||||||
enable_service %w[discourse gitea wiki xmpp]
|
enable_service %w[discourse gitea mediawiki ejabberd]
|
||||||
end
|
end
|
||||||
|
|
||||||
def reset_password(new_password, new_password_confirmation)
|
def reset_password(new_password, new_password_confirmation)
|
||||||
|
@ -15,7 +15,7 @@ class CreateAccount < ApplicationService
|
|||||||
|
|
||||||
if @invitation.present?
|
if @invitation.present?
|
||||||
update_invitation(user.id)
|
update_invitation(user.id)
|
||||||
exchange_xmpp_contacts
|
exchange_xmpp_contacts if Setting.ejabberd_enabled
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
7
app/views/admin/settings/_errors.html.erb
Normal file
7
app/views/admin/settings/_errors.html.erb
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<section>
|
||||||
|
<ul>
|
||||||
|
<% errors.full_messages.each do |msg| %>
|
||||||
|
<li><%= msg %></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</section>
|
@ -4,14 +4,9 @@
|
|||||||
<%= form_for(Setting.new, url: admin_settings_registrations_path) do |f| %>
|
<%= form_for(Setting.new, url: admin_settings_registrations_path) do |f| %>
|
||||||
<section>
|
<section>
|
||||||
<h3>Registrations</h3>
|
<h3>Registrations</h3>
|
||||||
|
|
||||||
<% if @errors && @errors.any? %>
|
<% if @errors && @errors.any? %>
|
||||||
<div>
|
<%= render partial: "admin/settings/errors", locals: { errors: @errors } %>
|
||||||
<ul>
|
|
||||||
<% @errors.full_messages.each do |msg| %>
|
|
||||||
<li><%= msg %></li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<label class="block">
|
<label class="block">
|
||||||
@ -29,7 +24,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<p class="pt-6 border-t border-gray-200">
|
<p class="pt-6 border-t border-gray-200 text-right">
|
||||||
<%= f.submit 'Save', class: "btn-md btn-blue w-full md:w-auto" %>
|
<%= f.submit 'Save', class: "btn-md btn-blue w-full md:w-auto" %>
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
17
app/views/admin/settings/services/_discourse.html.erb
Normal file
17
app/views/admin/settings/services/_discourse.html.erb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<h3>Discourse</h3>
|
||||||
|
<ul role="list">
|
||||||
|
<%= render FormElements::FieldsetToggleComponent.new(
|
||||||
|
form: f,
|
||||||
|
attribute: :discourse_enabled,
|
||||||
|
enabled: Setting.discourse_enabled?,
|
||||||
|
title: "Enable Discourse integration",
|
||||||
|
description: "Discourse configuration present and features enabled"
|
||||||
|
) %>
|
||||||
|
<% if Setting.discourse_enabled? %>
|
||||||
|
<%= render FormElements::FieldsetComponent.new(title: "Public URL") do %>
|
||||||
|
<%= f.text_field :discourse_public_url,
|
||||||
|
value: Setting.discourse_public_url,
|
||||||
|
class: "w-full", disabled: true %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
30
app/views/admin/settings/services/_ejabberd.html.erb
Normal file
30
app/views/admin/settings/services/_ejabberd.html.erb
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<h3>ejabberd (XMPP)</h3>
|
||||||
|
<ul role="list">
|
||||||
|
<%= render FormElements::FieldsetToggleComponent.new(
|
||||||
|
form: f,
|
||||||
|
attribute: :ejabberd_enabled,
|
||||||
|
enabled: Setting.ejabberd_enabled?,
|
||||||
|
title: "Enable ejabberd integration",
|
||||||
|
description: "ejabberd configuration present and features enabled"
|
||||||
|
) %>
|
||||||
|
<% if Setting.ejabberd_enabled? %>
|
||||||
|
<%= render FormElements::FieldsetComponent.new(title: "API URL") do %>
|
||||||
|
<%= f.text_field :ejabberd_api_url,
|
||||||
|
value: Setting.ejabberd_api_url,
|
||||||
|
class: "w-full", disabled: true %>
|
||||||
|
<% end %>
|
||||||
|
<%= render FormElements::FieldsetComponent.new(title: "Admin URL") do %>
|
||||||
|
<%= f.text_field :ejabberd_admin_url,
|
||||||
|
value: Setting.ejabberd_admin_url,
|
||||||
|
class: "w-full", disabled: true %>
|
||||||
|
<% end %>
|
||||||
|
<%= render FormElements::FieldsetComponent.new(
|
||||||
|
title: "Contact roster name",
|
||||||
|
description: "Used when exchanging contacts after signup from invitation"
|
||||||
|
) do %>
|
||||||
|
<%= f.text_field :ejabberd_buddy_roster,
|
||||||
|
value: Setting.ejabberd_buddy_roster,
|
||||||
|
class: "w-full" %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
17
app/views/admin/settings/services/_gitea.html.erb
Normal file
17
app/views/admin/settings/services/_gitea.html.erb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<h3>Gitea</h3>
|
||||||
|
<ul role="list">
|
||||||
|
<%= render FormElements::FieldsetToggleComponent.new(
|
||||||
|
form: f,
|
||||||
|
attribute: :gitea_enabled,
|
||||||
|
enabled: Setting.gitea_enabled?,
|
||||||
|
title: "Enable Gitea integration",
|
||||||
|
description: "Gitea configuration present and features enabled"
|
||||||
|
) %>
|
||||||
|
<% if Setting.gitea_enabled? %>
|
||||||
|
<%= render FormElements::FieldsetComponent.new(title: "Public URL") do %>
|
||||||
|
<%= f.text_field :gitea_public_url,
|
||||||
|
value: Setting.gitea_public_url,
|
||||||
|
class: "w-full", disabled: true %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
38
app/views/admin/settings/services/_lndhub.html.erb
Normal file
38
app/views/admin/settings/services/_lndhub.html.erb
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<h3>Lightning Network</h3>
|
||||||
|
<ul role="list">
|
||||||
|
<%= render FormElements::FieldsetToggleComponent.new(
|
||||||
|
form: f,
|
||||||
|
attribute: :lndhub_enabled,
|
||||||
|
enabled: Setting.lndhub_enabled?,
|
||||||
|
title: "Enable LNDHub integration",
|
||||||
|
description: "LNDHub configuration present and wallet features enabled"
|
||||||
|
) %>
|
||||||
|
<% if Setting.lndhub_enabled? %>
|
||||||
|
<%= render FormElements::FieldsetComponent.new(title: "API URL") do %>
|
||||||
|
<%= f.text_field :lndhub_api_url,
|
||||||
|
value: Setting.lndhub_api_url,
|
||||||
|
class: "w-full", disabled: true %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<%= render FormElements::FieldsetToggleComponent.new(
|
||||||
|
form: f,
|
||||||
|
attribute: :lndhub_admin_enabled,
|
||||||
|
enabled: Setting.lndhub_admin_enabled?,
|
||||||
|
title: "Enable LNDHub admin panel",
|
||||||
|
description: "LNDHub database configuration present and admin panel enabled"
|
||||||
|
) %>
|
||||||
|
<%= render FormElements::FieldsetToggleComponent.new(
|
||||||
|
form: f,
|
||||||
|
attribute: :lndhub_keysend_enabled,
|
||||||
|
enabled: Setting.lndhub_keysend_enabled?,
|
||||||
|
title: "Enable keysend payments",
|
||||||
|
description: "Allow users to receive invoice-less payments to their Lightning Address"
|
||||||
|
) %>
|
||||||
|
<% if Setting.lndhub_keysend_enabled? %>
|
||||||
|
<%= render FormElements::FieldsetComponent.new(title: "Public key", description: "The public key of the Lightning node used by LNDHub") do %>
|
||||||
|
<%= f.text_field :lndhub_public_key,
|
||||||
|
value: Setting.lndhub_public_key,
|
||||||
|
class: "w-full", disabled: true %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
17
app/views/admin/settings/services/_mastodon.html.erb
Normal file
17
app/views/admin/settings/services/_mastodon.html.erb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<h3>Mastodon</h3>
|
||||||
|
<ul role="list">
|
||||||
|
<%= render FormElements::FieldsetToggleComponent.new(
|
||||||
|
form: f,
|
||||||
|
attribute: :mastodon_enabled,
|
||||||
|
enabled: Setting.mastodon_enabled?,
|
||||||
|
title: "Enable Mastodon integration",
|
||||||
|
description: "Mastodon configuration present and features enabled"
|
||||||
|
) %>
|
||||||
|
<% if Setting.mastodon_enabled? %>
|
||||||
|
<%= render FormElements::FieldsetComponent.new(title: "Public URL") do %>
|
||||||
|
<%= f.text_field :mastodon_public_url,
|
||||||
|
value: Setting.mastodon_public_url,
|
||||||
|
class: "w-full", disabled: true %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
17
app/views/admin/settings/services/_mediawiki.html.erb
Normal file
17
app/views/admin/settings/services/_mediawiki.html.erb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<h3>MediaWiki</h3>
|
||||||
|
<ul role="list">
|
||||||
|
<%= render FormElements::FieldsetToggleComponent.new(
|
||||||
|
form: f,
|
||||||
|
attribute: :mediawiki_enabled,
|
||||||
|
enabled: Setting.mediawiki_enabled?,
|
||||||
|
title: "Enable MediaWiki integration",
|
||||||
|
description: "MediaWiki configuration present and features enabled"
|
||||||
|
) %>
|
||||||
|
<% if Setting.mediawiki_enabled? %>
|
||||||
|
<%= render FormElements::FieldsetComponent.new(title: "Public URL") do %>
|
||||||
|
<%= f.text_field :mediawiki_public_url,
|
||||||
|
value: Setting.mediawiki_public_url,
|
||||||
|
class: "w-full", disabled: true %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
10
app/views/admin/settings/services/_nostr.html.erb
Normal file
10
app/views/admin/settings/services/_nostr.html.erb
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<h3>Nostr</h3>
|
||||||
|
<ul role="list">
|
||||||
|
<%= render FormElements::FieldsetToggleComponent.new(
|
||||||
|
form: f,
|
||||||
|
attribute: :nostr_enabled,
|
||||||
|
enabled: Setting.nostr_enabled?,
|
||||||
|
title: "Enable Nostr integration (experimental)",
|
||||||
|
description: "Allow adding nostr pubkeys and resolve user addresses via NIP-05"
|
||||||
|
) %>
|
||||||
|
</ul>
|
@ -1,39 +1,23 @@
|
|||||||
<%= render HeaderComponent.new(title: "Settings") %>
|
<%= render HeaderComponent.new(title: "Settings") %>
|
||||||
|
|
||||||
<%= render MainWithSidenavComponent.new(sidenav_partial: 'shared/admin_sidenav_settings') do %>
|
<%= render MainWithSidenavComponent.new(sidenav_partial: 'shared/admin_sidenav_settings') do %>
|
||||||
<section>
|
<%= form_for(Setting.new, url: admin_settings_services_path) do |f| %>
|
||||||
<h3>Lightning Network</h3>
|
<%= hidden_field_tag :service, @service %>
|
||||||
<%= form_for(Setting.new, url: admin_settings_services_path) do |f| %>
|
|
||||||
<% if @errors && @errors.any? %>
|
|
||||||
<div>
|
|
||||||
<ul>
|
|
||||||
<% @errors.full_messages.each do |msg| %>
|
|
||||||
<li><%= msg %></li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<ul role="list" class="mt-2 divide-y divide-gray-200">
|
<% if @errors && @errors.any? %>
|
||||||
<li class="flex items-center justify-between py-6">
|
<section>
|
||||||
<div class="flex flex-col">
|
<%= render partial: "admin/settings/errors", locals: { errors: @errors } %>
|
||||||
<label class="font-bold mb-1">Enable LNDHub integration</label>
|
</section>
|
||||||
<p class="text-gray-500">LNDHub configuration present and wallet features enabled</p>
|
|
||||||
</div>
|
|
||||||
<%= f.check_box :lndhub_enabled, checked: Setting.lndhub_enabled?,
|
|
||||||
disabled: true,
|
|
||||||
class: "relative ml-4 inline-flex flex-shrink-0" %>
|
|
||||||
</li>
|
|
||||||
<li class="flex items-center justify-between py-6">
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<label class="font-bold mb-1">Enable LNDHub admin panel</label>
|
|
||||||
<p class="text-gray-500">LNDHub database configuration present and admin panel enabled</p>
|
|
||||||
</div>
|
|
||||||
<%= f.check_box :lndhub_admin_enabled, checked: Setting.lndhub_admin_enabled?,
|
|
||||||
disabled: true,
|
|
||||||
class: "relative ml-4 inline-flex flex-shrink-0" %>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
</section>
|
|
||||||
|
<section>
|
||||||
|
<%= render partial: @service, locals: { f: f } %>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<p class="pt-6 border-t border-gray-200 text-right">
|
||||||
|
<%= f.submit 'Save', class: "btn-md btn-blue w-full md:w-auto" %>
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
@ -65,28 +65,87 @@
|
|||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h3>Services</h3>
|
<h3>Services</h3>
|
||||||
<table class="sm:w-1/4">
|
<table class="divided">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Enabled</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
<% if Setting.discourse_enabled %>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Discourse</td>
|
<td>Discourse</td>
|
||||||
<td><%= check_box_tag 'service_discourse', 'enabled', @services_enabled.include?("discourse"), disabled: true %></td>
|
<td>
|
||||||
|
<%= render FormElements::ToggleComponent.new(
|
||||||
|
enabled: @services_enabled.include?("discourse"),
|
||||||
|
input_enabled: false
|
||||||
|
) %>
|
||||||
|
</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<%= link_to "Open profile", "#{Setting.discourse_public_url}/u/#{@user.cn}/summary", class: "btn-sm btn-gray" %>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
<% if Setting.gitea_enabled %>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Gitea</td>
|
<td>Gitea</td>
|
||||||
<td><%= check_box_tag 'service_gitea', 'enabled', @services_enabled.include?("gitea"), disabled: true %></td>
|
<td>
|
||||||
|
<%= render FormElements::ToggleComponent.new(
|
||||||
|
enabled: @services_enabled.include?("gitea"),
|
||||||
|
input_enabled: false
|
||||||
|
) %>
|
||||||
|
</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<%= link_to "Open profile", "#{Setting.gitea_public_url}/#{@user.cn}", class: "btn-sm btn-gray" %>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
<% if Setting.mastodon_enabled %>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Mastodon</td>
|
<td>Mastodon</td>
|
||||||
<td><%= check_box_tag 'service_mastodon', 'enabled', @services_enabled.include?("mastodon"), disabled: true %></td>
|
<td>
|
||||||
|
<%= render FormElements::ToggleComponent.new(
|
||||||
|
enabled: @services_enabled.include?("mastodon"),
|
||||||
|
input_enabled: false
|
||||||
|
) %>
|
||||||
|
</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<%= link_to "Open profile", "#{Setting.mastodon_public_url}/@#{@user.cn}", class: "btn-sm btn-gray" %>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
<% if Setting.mediawiki_enabled %>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Wiki</td>
|
<td>MediaWiki</td>
|
||||||
<td><%= check_box_tag 'service_wiki', 'enabled', @services_enabled.include?("wiki"), disabled: true %></td>
|
<td>
|
||||||
|
<%= render FormElements::ToggleComponent.new(
|
||||||
|
enabled: @services_enabled.include?("mediawiki"),
|
||||||
|
input_enabled: false
|
||||||
|
) %>
|
||||||
|
</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<%= link_to "Open profile", "#{Setting.mediawiki_public_url}/Special:Contributions/#{@user.cn}", class: "btn-sm btn-gray" %>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
<% if Setting.ejabberd_enabled %>
|
||||||
<tr>
|
<tr>
|
||||||
<td>XMPP</td>
|
<td>XMPP (ejabberd)</td>
|
||||||
<td><%= check_box_tag 'service_xmpp', 'enabled', @services_enabled.include?("xmpp"), disabled: true %></td>
|
<td>
|
||||||
|
<%= render FormElements::ToggleComponent.new(
|
||||||
|
enabled: @services_enabled.include?("ejabberd"),
|
||||||
|
input_enabled: false
|
||||||
|
) %>
|
||||||
|
</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<% if Setting.ejabberd_admin_url.present? %>
|
||||||
|
<%= link_to "Open profile", "#{Setting.ejabberd_admin_url}/server/#{@user.ou}/user/#{@user.cn}/", class: "btn-sm btn-gray" %>
|
||||||
|
<% end %>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<% end %>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</section>
|
</section>
|
||||||
|
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-x"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-x <%= custom_class %>"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
|
||||||
|
Before Width: | Height: | Size: 299 B After Width: | Height: | Size: 320 B |
@ -6,6 +6,9 @@
|
|||||||
name: "Services", path: admin_settings_services_path, icon: "grid",
|
name: "Services", path: admin_settings_services_path, icon: "grid",
|
||||||
active: current_page?(admin_settings_services_path)
|
active: current_page?(admin_settings_services_path)
|
||||||
) %>
|
) %>
|
||||||
|
<% if current_page?(admin_settings_services_path) %>
|
||||||
|
<%= render partial: "shared/admin_sidenav_settings_services" %>
|
||||||
|
<% end %>
|
||||||
<%= render SidenavLinkComponent.new(
|
<%= render SidenavLinkComponent.new(
|
||||||
name: "Security", path: "#", icon: "shield", disabled: true
|
name: "Security", path: "#", icon: "shield", disabled: true
|
||||||
) %>
|
) %>
|
||||||
|
49
app/views/shared/_admin_sidenav_settings_services.html.erb
Normal file
49
app/views/shared/_admin_sidenav_settings_services.html.erb
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<%= render SidenavLinkComponent.new(
|
||||||
|
level: 2,
|
||||||
|
name: "Discourse",
|
||||||
|
path: admin_settings_services_path(params: { s: "discourse" }),
|
||||||
|
icon: Setting.discourse_enabled? ? "check" : "x",
|
||||||
|
active: current_page?(admin_settings_services_path(params: { s: "discourse" })),
|
||||||
|
) %>
|
||||||
|
<%= render SidenavLinkComponent.new(
|
||||||
|
level: 2,
|
||||||
|
name: "ejabberd",
|
||||||
|
path: admin_settings_services_path(params: { s: "ejabberd" }),
|
||||||
|
icon: Setting.ejabberd_enabled? ? "check" : "x",
|
||||||
|
active: current_page?(admin_settings_services_path(params: { s: "ejabberd" })),
|
||||||
|
) %>
|
||||||
|
<%= render SidenavLinkComponent.new(
|
||||||
|
level: 2,
|
||||||
|
name: "Gitea",
|
||||||
|
path: admin_settings_services_path(params: { s: "gitea" }),
|
||||||
|
icon: Setting.gitea_enabled? ? "check" : "x",
|
||||||
|
active: current_page?(admin_settings_services_path(params: { s: "gitea" })),
|
||||||
|
) %>
|
||||||
|
<%= render SidenavLinkComponent.new(
|
||||||
|
level: 2,
|
||||||
|
name: "LNDHub",
|
||||||
|
path: admin_settings_services_path(params: { s: "lndhub" }),
|
||||||
|
icon: Setting.lndhub_enabled? ? "check" : "x",
|
||||||
|
active: current_page?(admin_settings_services_path(params: { s: "lndhub" })),
|
||||||
|
) %>
|
||||||
|
<%= render SidenavLinkComponent.new(
|
||||||
|
level: 2,
|
||||||
|
name: "Mastodon",
|
||||||
|
path: admin_settings_services_path(params: { s: "mastodon" }),
|
||||||
|
icon: Setting.mastodon_enabled? ? "check" : "x",
|
||||||
|
active: current_page?(admin_settings_services_path(params: { s: "mastodon" })),
|
||||||
|
) %>
|
||||||
|
<%= render SidenavLinkComponent.new(
|
||||||
|
level: 2,
|
||||||
|
name: "MediaWiki",
|
||||||
|
path: admin_settings_services_path(params: { s: "mediawiki" }),
|
||||||
|
icon: Setting.mediawiki_enabled? ? "check" : "x",
|
||||||
|
active: current_page?(admin_settings_services_path(params: { s: "mediawiki" })),
|
||||||
|
) %>
|
||||||
|
<%= render SidenavLinkComponent.new(
|
||||||
|
level: 2,
|
||||||
|
name: "Nostr",
|
||||||
|
path: admin_settings_services_path(params: { s: "nostr" }),
|
||||||
|
icon: Setting.nostr_enabled? ? "check" : "x",
|
||||||
|
active: current_page?(admin_settings_services_path(params: { s: "nostr" })),
|
||||||
|
) %>
|
@ -18,4 +18,33 @@ RSpec.describe 'Admin/global settings', type: :feature do
|
|||||||
click_button "Save"
|
click_button "Save"
|
||||||
expect(Setting.reserved_usernames).to eq(['Kosmos', 'Kredits'])
|
expect(Setting.reserved_usernames).to eq(['Kosmos', 'Kredits'])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "Service settings" do
|
||||||
|
scenario "Opening service settings shows page for first service" do
|
||||||
|
visit admin_settings_services_path
|
||||||
|
|
||||||
|
expect(current_url).to eq(admin_settings_services_url(params: { s: "discourse" }))
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "View ejabberd settings" do
|
||||||
|
visit admin_settings_services_path(params: { s: "ejabberd" })
|
||||||
|
|
||||||
|
expect(page).to have_content("Enable ejabberd integration")
|
||||||
|
expect(page).to have_field("API URL",
|
||||||
|
with: "http://xmpp.example.com/api",
|
||||||
|
disabled: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Disable ejabberd integration" do
|
||||||
|
visit admin_settings_services_path(params: { s: "ejabberd" })
|
||||||
|
expect(page).to have_checked_field("setting[ejabberd_enabled]")
|
||||||
|
|
||||||
|
uncheck "setting[ejabberd_enabled]"
|
||||||
|
click_button "Save"
|
||||||
|
|
||||||
|
expect(current_url).to eq(admin_settings_services_url(params: { s: "ejabberd" }))
|
||||||
|
expect(page).to_not have_checked_field("setting[ejabberd_enabled]")
|
||||||
|
expect(page).to_not have_field("API URL", disabled: true)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -17,9 +17,9 @@ RSpec.describe XmppExchangeContactsJob, type: :job do
|
|||||||
perform_enqueued_jobs { job }
|
perform_enqueued_jobs { job }
|
||||||
|
|
||||||
expect(WebMock).to have_requested(:post, "http://xmpp.example.com/api/add_rosteritem")
|
expect(WebMock).to have_requested(:post, "http://xmpp.example.com/api/add_rosteritem")
|
||||||
.with { |req| req.body == '{"localuser":"isaacnewton","localhost":"kosmos.org","user":"willherschel","host":"kosmos.org","nick":"willherschel","group":"Friends","subs":"both"}' }
|
.with { |req| req.body == '{"localuser":"isaacnewton","localhost":"kosmos.org","user":"willherschel","host":"kosmos.org","nick":"willherschel","group":"Buddies","subs":"both"}' }
|
||||||
expect(WebMock).to have_requested(:post, "http://xmpp.example.com/api/add_rosteritem")
|
expect(WebMock).to have_requested(:post, "http://xmpp.example.com/api/add_rosteritem")
|
||||||
.with { |req| req.body == '{"localuser":"willherschel","localhost":"kosmos.org","user":"isaacnewton","host":"kosmos.org","nick":"isaacnewton","group":"Friends","subs":"both"}' }
|
.with { |req| req.body == '{"localuser":"willherschel","localhost":"kosmos.org","user":"isaacnewton","host":"kosmos.org","nick":"isaacnewton","group":"Buddies","subs":"both"}' }
|
||||||
end
|
end
|
||||||
|
|
||||||
after do
|
after do
|
||||||
|
Loading…
x
Reference in New Issue
Block a user