diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb
index f50235a..c5bd8f8 100644
--- a/app/controllers/settings_controller.rb
+++ b/app/controllers/settings_controller.rb
@@ -45,8 +45,8 @@ class SettingsController < ApplicationController
def user_params
params.require(:user).permit(preferences: [
- lightning: [:notify_sats_received],
- xmpp: [:exchange_contacts_with_invitees]
+ :lightning_notify_sats_received,
+ :xmpp_exchange_contacts_with_invitees
])
end
end
diff --git a/app/controllers/webhooks_controller.rb b/app/controllers/webhooks_controller.rb
index 9db08d9..7025580 100644
--- a/app/controllers/webhooks_controller.rb
+++ b/app/controllers/webhooks_controller.rb
@@ -12,7 +12,7 @@ class WebhooksController < ApplicationController
end
user = User.find_by!(ln_account: payload[:user_login])
- notify = user.preferences.dig("lightning", "notify_sats_received")
+ notify = user.preferences[:lightning_notify_sats_received]
case notify
when "xmpp"
notify_xmpp(user.address, payload[:amount], payload[:memo])
diff --git a/app/models/user.rb b/app/models/user.rb
index f0f595f..695c06c 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,7 +1,7 @@
class User < ApplicationRecord
include EmailValidatable
- serialize :preferences, Hash, default: {}
+ serialize :preferences, UserPreferences
# Relations
has_many :invitations, dependent: :destroy
@@ -64,7 +64,7 @@ class User < ApplicationRecord
if inviter.present?
if Setting.ejabberd_enabled? &&
- inviter.pref_enabled?("xmpp:exchange_contacts_with_invitees")
+ inviter.preferences[:xmpp_exchange_contacts_with_invitees]
exchange_xmpp_contact_with_inviter
end
end
@@ -138,11 +138,6 @@ class User < ApplicationRecord
ldap.delete_attribute(dn,:service)
end
- def pref_enabled?(key)
- value = preferences.dig(*key.split(":"))
- [true, "true", "enabled", 1].include?(value)
- end
-
def exchange_xmpp_contact_with_inviter
return unless inviter.services_enabled.include?("xmpp") &&
services_enabled.include?("xmpp")
diff --git a/app/models/user_preferences.rb b/app/models/user_preferences.rb
new file mode 100644
index 0000000..ffdf7f6
--- /dev/null
+++ b/app/models/user_preferences.rb
@@ -0,0 +1,29 @@
+DEFAULT_PREFS = YAML.load_file("#{Rails.root}/config/default_preferences.yml")
+
+class UserPreferences
+ def self.dump(value)
+ process(value).to_yaml
+ end
+
+ def self.load(string)
+ stored_prefs = YAML.load(string || "{}")
+ DEFAULT_PREFS.merge(stored_prefs).with_indifferent_access
+ end
+
+ def self.is_integer?(value)
+ value.to_i.to_s == value
+ end
+
+ def self.process(hash)
+ hash.each do |key, value|
+ if value == "true"
+ hash[key] = true
+ elsif value == "false"
+ hash[key] = false
+ elsif value.is_a?(String) && is_integer?(value)
+ hash[key] = value.to_i
+ end
+ end
+ hash.stringify_keys!.to_h
+ end
+end
diff --git a/app/views/settings/_lightning.html.erb b/app/views/settings/_lightning.html.erb
index b7ad6e2..6e75343 100644
--- a/app/views/settings/_lightning.html.erb
+++ b/app/views/settings/_lightning.html.erb
@@ -8,13 +8,11 @@
description: "Notify me when sats are sent to my Lightning Address"
) do %>
<% f.fields_for :preferences do |p| %>
- <% p.fields_for :lightning do |l| %>
- <%= l.select :notify_sats_received, options_for_select([
- ["off", "off"],
- ["Chat (Jabber)", "xmpp"],
- ["E-Mail", "email"]
- ], selected: @user.preferences.dig('lightning', 'notify_sats_received')) %>
- <% end %>
+ <%= p.select :lightning_notify_sats_received, options_for_select([
+ ["off", "disabled"],
+ ["Chat (Jabber)", "xmpp"],
+ ["E-Mail", "email"]
+ ], selected: @user.preferences[:lightning_notify_sats_received]) %>
<% end %>
<% end %>
diff --git a/app/views/settings/_xmpp.html.erb b/app/views/settings/_xmpp.html.erb
index 3ce4e91..a13ce70 100644
--- a/app/views/settings/_xmpp.html.erb
+++ b/app/views/settings/_xmpp.html.erb
@@ -3,8 +3,8 @@
Contacts
<%= render FormElements::FieldsetToggleComponent.new(
- field_name: "user[preferences][xmpp][exchange_contacts_with_invitees]",
- enabled: @user.pref_enabled?("xmpp:exchange_contacts_with_invitees"),
+ field_name: "user[preferences][xmpp_exchange_contacts_with_invitees]",
+ enabled: @user.preferences[:xmpp_exchange_contacts_with_invitees],
title: "Exchange contacts when invited user signs up",
description: "Add each others contacts, so you can chat with them immediately"
) %>
diff --git a/config/default_preferences.yml b/config/default_preferences.yml
new file mode 100644
index 0000000..ff7f051
--- /dev/null
+++ b/config/default_preferences.yml
@@ -0,0 +1,2 @@
+lightning_notify_sats_received: disabled # or xmpp, email
+xmpp_exchange_contacts_with_invitees: true
diff --git a/spec/models/user_preferences_spec.rb b/spec/models/user_preferences_spec.rb
new file mode 100644
index 0000000..4bb7b42
--- /dev/null
+++ b/spec/models/user_preferences_spec.rb
@@ -0,0 +1,41 @@
+require 'rails_helper'
+
+RSpec.describe UserPreferences, type: :model do
+ let(:default_prefs) { YAML.load_file("#{Rails.root}/config/default_preferences.yml") }
+
+ describe ".load" do
+ it "provides default values when no preferences are stored yet" do
+ expect(UserPreferences.load(nil)).to eq(default_prefs)
+ end
+
+ it "provides default values for unset preferences" do
+ prefs = UserPreferences.load("lightning_notify_sats_received: xmpp")
+ expect(prefs[:lightning_notify_sats_received]).to eq("xmpp")
+ expect(prefs[:xmpp_exchange_contacts_with_invitees]).to eq(true)
+ end
+ end
+
+ describe ".process" do
+ it "turns all keys into strings" do
+ res = UserPreferences.process({ foo: "bar" })
+ expect(res[:foo]).to be(nil)
+ expect(res['foo']).to eq("bar")
+ end
+
+ it "converts value 'true' to boolean" do
+ res = UserPreferences.process({ lightning_notify_sats_received: "true" })
+ expect(res['lightning_notify_sats_received']).to be(true)
+ end
+
+ it "converts value 'false' to boolean" do
+ res = UserPreferences.process({ lightning_notify_sats_received: "false" })
+ expect(res['lightning_notify_sats_received']).to be(false)
+ end
+
+ it "converts value string with integer into integer" do
+ res = UserPreferences.process({ lightning_notify_sats_received_threshold: 1000 })
+ expect(res['lightning_notify_sats_received_threshold']).to be_a(Integer)
+ expect(res['lightning_notify_sats_received_threshold']).to eq(1000)
+ end
+ end
+end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index a36458f..c1105c9 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -140,7 +140,7 @@ RSpec.describe User, type: :model do
before do
# TODO remove when defaults are implemented
- user.update! preferences: {"xmpp" => { "exchange_contacts_with_invitees" => true }}
+ user.update! preferences: { xmpp_exchange_contacts_with_invitees: true }
Invitation.create! user: user, invited_user_id: guest.id, used_at: DateTime.now
allow_any_instance_of(User).to receive(:enable_service).and_return(true)
end
@@ -152,7 +152,7 @@ RSpec.describe User, type: :model do
context "automatic contact exchange disabled" do
before do
- user.update! preferences: {"xmpp" => { "exchange_contacts_with_invitees" => false }}
+ user.update! preferences: { xmpp_exchange_contacts_with_invitees: false }
end
it "does not exchange XMPP contacts with the inviter" do
@@ -162,50 +162,4 @@ RSpec.describe User, type: :model do
end
end
end
-
- describe "#pref_enabled?" do
- describe "preference not set" do
- # TODO return default value
- it "returns false" do
- expect(user.pref_enabled?("lightning:notify_sats_received")).to be(false)
- end
- end
-
- describe "preference is set" do
- it "returns true for boolean true" do
- user.preferences.merge!({"lightning" => {"notify_sats_received" => true}})
- expect(user.pref_enabled?("lightning:notify_sats_received")).to be(true)
- end
-
- it "returns true for string 'true'" do
- user.preferences.merge!({"lightning" => {"notify_sats_received" => "true"}})
- expect(user.pref_enabled?("lightning:notify_sats_received")).to be(true)
- end
-
- it "returns true for string 'enabled'" do
- user.preferences.merge!({"lightning" => {"notify_sats_received" => "enabled"}})
- expect(user.pref_enabled?("lightning:notify_sats_received")).to be(true)
- end
-
- it "returns true for integer 1" do
- user.preferences.merge!({"lightning" => {"notify_sats_received" => 1}})
- expect(user.pref_enabled?("lightning:notify_sats_received")).to be(true)
- end
-
- it "returns false for boolean false" do
- user.preferences.merge!({"lightning" => {"notify_sats_received" => false}})
- expect(user.pref_enabled?("lightning:notify_sats_received")).to be(false)
- end
-
- it "returns false for string 'false'" do
- user.preferences.merge!({"lightning" => {"notify_sats_received" => "false"}})
- expect(user.pref_enabled?("lightning:notify_sats_received")).to be(false)
- end
-
- it "returns false for integer 0" do
- user.preferences.merge!({"lightning" => {"notify_sats_received" => 0}})
- expect(user.pref_enabled?("lightning:notify_sats_received")).to be(false)
- end
- end
- end
end
diff --git a/spec/requests/webhooks_spec.rb b/spec/requests/webhooks_spec.rb
index d38cf7c..96a3b8f 100644
--- a/spec/requests/webhooks_spec.rb
+++ b/spec/requests/webhooks_spec.rb
@@ -68,7 +68,7 @@ RSpec.describe "Webhooks", type: :request do
context "notification preference set to 'xmpp'" do
before do
- user.update! preferences: { "lightning" => { "notify_sats_received" => "xmpp" }}
+ user.update! preferences: { lightning_notify_sats_received: "xmpp" }
post "/webhooks/lndhub", params: payload.to_json
end
@@ -87,7 +87,7 @@ RSpec.describe "Webhooks", type: :request do
context "notification preference set to 'email'" do
before do
- user.update! preferences: { "lightning" => { "notify_sats_received" => "email" }}
+ user.update! preferences: { lightning_notify_sats_received: "email" }
post "/webhooks/lndhub", params: payload.to_json
end