Skip to content

Commit

Permalink
Merge pull request #4 from paviliondev/merge_x_discourse_subscriptions
Browse files Browse the repository at this point in the history
Add x-discourse-subscriptions into discourse-subscription-server
  • Loading branch information
angusmcleod authored Jan 10, 2024
2 parents d9a0fe7 + bc762ee commit 7b778cb
Show file tree
Hide file tree
Showing 14 changed files with 260 additions and 16 deletions.
50 changes: 50 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
GEM
remote: https://rubygems.org/
specs:
ast (2.4.2)
json (2.6.3)
language_server-protocol (3.17.0.3)
parallel (1.23.0)
parser (3.2.2.4)
ast (~> 2.4.1)
racc
racc (1.7.3)
rainbow (3.1.1)
regexp_parser (2.8.2)
rexml (3.2.6)
rubocop (1.57.2)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.2.2.4)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.28.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.30.0)
parser (>= 3.2.1.0)
rubocop-capybara (2.19.0)
rubocop (~> 1.41)
rubocop-discourse (3.4.1)
rubocop (>= 1.1.0)
rubocop-rspec (>= 2.0.0)
rubocop-factory_bot (2.24.0)
rubocop (~> 1.33)
rubocop-rspec (2.25.0)
rubocop (~> 1.40)
rubocop-capybara (~> 2.17)
rubocop-factory_bot (~> 2.22)
ruby-progressbar (1.13.0)
unicode-display_width (2.5.0)

PLATFORMS
arm64-darwin-22
x86_64-linux

DEPENDENCIES
rubocop-discourse

BUNDLED WITH
2.4.13
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

class SubscriptionServer::UserAuthorizationsController < ApplicationController
before_action :ensure_logged_in

def destroy
params.require(:domain)
current_user.remove_subscription_domain(params[:domain])
render json: success_json
end
end
8 changes: 0 additions & 8 deletions config/locales/client.en.yml

This file was deleted.

2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
get '' => 'server#index', defaults: { format: 'json' }
get 'user-subscriptions' => 'user_subscriptions#index', defaults: { format: 'json' }
get 'messages' => 'messages#index', defaults: { format: 'json' }
delete 'user-authorizations' => 'user_authorizations#destroy', defaults: { format: 'json' }
end

Discourse::Application.routes.append do
mount ::SubscriptionServer::Engine, at: "/subscription-server"
get '/subscribe' => 'discourse_subscriptions/subscribe#index'
end
6 changes: 4 additions & 2 deletions config/settings.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
plugins:
subscription_server_enabled: true
subscription_server_enabled:
client: true
default: true
subscription_server_supplier_name: ''
subscription_server_subscriptions:
type: list
default: ''
default: ''
5 changes: 0 additions & 5 deletions coverage/.last_run.json

This file was deleted.

30 changes: 30 additions & 0 deletions extensions/discourse_subscriptions_coupons_controller_extension.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true
module DiscourseSubscriptionsCouponsControllerExtension
def create
params.require([:promo, :discount_type, :discount, :active, :applies_to_products])
begin
coupon_params = {
duration: 'forever',
max_redemptions: params[:max_redemptions] || 1,
applies_to: {
products: params[:applies_to_products]
}
}

case params[:discount_type]
when 'amount'
coupon_params[:amount_off] = params[:discount].to_i * 100
coupon_params[:currency] = SiteSetting.discourse_subscriptions_currency
when 'percent'
coupon_params[:percent_off] = params[:discount]
end

coupon = ::Stripe::Coupon.create(coupon_params)
promo_code = ::Stripe::PromotionCode.create({ coupon: coupon[:id], code: params[:promo] }) if coupon.present?

render_json_dump promo_code
rescue ::Stripe::InvalidRequestError => e
render_json_error e.message
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true
module DiscourseSubscriptionsProductsControllerExtension
def show
begin
product = ::Stripe::Product.retrieve(params[:id])

if product[:metadata][:hidden].present?
product[:metadata][:hidden] = ActiveRecord::Type::Boolean.new.cast(product[:metadata][:hidden])
end

render_json_dump product

rescue ::Stripe::InvalidRequestError => e
render_json_error e.message
end
end

private def product_params
params.permit!

{
name: params[:name],
active: params[:active],
statement_descriptor: params[:statement_descriptor],
metadata: {
description: params.dig(:metadata, :description),
repurchaseable: params.dig(:metadata, :repurchaseable),
hidden: params.dig(:metadata, :hidden)
}
}
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true
module DiscourseSubscriptionsSubscribeControllerExtension
private def serialize_product(product)
{
id: product[:id],
name: product[:name],
description: PrettyText.cook(product[:metadata][:description]),
subscribed: current_user_products.include?(product[:id]),
repurchaseable: product[:metadata][:repurchaseable],
hidden: ActiveRecord::Type::Boolean.new.cast(product[:metadata][:hidden])
}
end

private def serialize_plans(plans)
plans[:data].reduce([]) do |result, p|
plan = p.to_h
if plan[:nickname] != "hidden"
result << plan.slice(:id, :unit_amount, :currency, :type, :recurring, :nickname)
end
result
end.sort_by { |plan| plan[:amount] }
end
end
2 changes: 1 addition & 1 deletion lib/subscription_server/provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
class SubscriptionServer::Provider
attr_reader :user

def initialize(user)
def initialize(user = nil)
@user = user
end

Expand Down
4 changes: 4 additions & 0 deletions lib/subscription_server/providers/stripe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,8 @@ def subscriptions(product_ids, resource_name)
result
end
end

def self.discourse_subscriptions_installed?
new.discourse_subscriptions_installed?
end
end
53 changes: 53 additions & 0 deletions plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@

enabled_site_setting :subscription_server_enabled

DiscourseEvent.on(:after_plugin_activation) do
sorted_pugins = Discourse.plugins.sort_by do |p|
p&.name == 'discourse-subscription-server' ? 1 : 0
end
Discourse.instance_variable_set(:@plugins, sorted_pugins)
end

after_initialize do
%w[
../lib/subscription_server/engine.rb
Expand All @@ -21,6 +28,7 @@
../lib/subscription_server/extensions/user_api_keys_controller.rb
../config/routes.rb
../app/controllers/subscription_server/user_subscriptions_controller.rb
../app/controllers/subscription_server/user_authorizations_controller.rb
../app/controllers/subscription_server/messages_controller.rb
../app/controllers/subscription_server/server_controller.rb
../app/serializers/subscription_server/message_serializer.rb
Expand Down Expand Up @@ -62,6 +70,17 @@
save_custom_fields(true)
end

add_to_class(:user, :remove_subscription_domain) do |domain|
self._custom_fields.where(
"name LIKE '#{SubscriptionServer::UserSubscriptions::DOMAINS_KEY_PREFIX}%'"
).each do |field|
value_arr = field.value.split('|')
value_arr = value_arr.reject { |d| d === domain }
field.value = value_arr.join('|')
field.save!
end
end

add_to_class(:user, :subscription_product_domains) do |resource_name, provider_name, product_id|
key = subscription_product_domain_key(resource_name, provider_name, product_id)
product_domains = custom_fields[key]
Expand Down Expand Up @@ -94,4 +113,38 @@
result
end
end

add_to_serializer(:user, :subscription_domains) { user.subscription_domains }

if SubscriptionServer::Stripe.discourse_subscriptions_installed?
%w[
../extensions/discourse_subscriptions_coupons_controller_extension.rb
../extensions/discourse_subscriptions_products_controller_extension.rb
../extensions/discourse_subscriptions_subscriber_controller_extension.rb
].each do |path|
load File.expand_path(path, __FILE__)
end
DiscourseSubscriptions::SubscribeController.prepend DiscourseSubscriptionsSubscribeControllerExtension
DiscourseSubscriptions::Admin::CouponsController.prepend DiscourseSubscriptionsCouponsControllerExtension
DiscourseSubscriptions::Admin::ProductsController.prepend DiscourseSubscriptionsProductsControllerExtension

require 'csv'
module ::DiscourseSubscriptions
def self.class_update_subscriptions_from_csv(path)
rows = CSV.read(path)
return unless rows.present?

rows.each do |row|
DiscourseSubscriptions::Subscription
.joins(:customer)
.where("discourse_subscriptions_customers.customer_id = :customer_id AND discourse_subscriptions_subscriptions.external_id = :subscription_id",
customer_id: row[0].strip,
subscription_id: row[1].strip
).update_all(
external_id: row[2].strip
)
end
end
end
end
end
9 changes: 9 additions & 0 deletions spec/components/subscription_server/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,13 @@
expect(user.subscription_domains.first[:domains]).to eq([domain])
expect(user.subscription_domains.first[:domain_limit]).to eq(1)
end

it "#remove_subscription_domain" do
user.add_subscription_product_domain(domain, resource, provider, product_id)
user.add_subscription_product_domain(domain, resource, provider, "prod_12345")
user.remove_subscription_domain(domain)
user.reload
expect(user.custom_fields[user.subscription_product_domain_key(resource, provider, product_id)]).to eq("")
expect(user.custom_fields[user.subscription_product_domain_key(resource, provider, "prod_12345")]).to eq("")
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# frozen_string_literal: true

describe SubscriptionServer::UserAuthorizationsController do
let(:user) { Fabricate(:user) }
let(:provider) { "stripe" }
let(:product_id) { "prod_CBTNpi3fqWWkq0" }
let(:product_slug) { "business" }
let(:resource) { "custom_wizard" }
let(:domain) { "demo.pavilion.tech" }

it "requires a user" do
delete "/subscription-server/user-authorizations"
expect(response.status).to eq(403)
end

context "with a user" do
before do
sign_in(user)
end

describe "#destroy" do

it "requires a domain" do
delete "/subscription-server/user-authorizations"
expect(response.status).to eq(400)
end

it "removes the domain from all of the user's products" do
user.add_subscription_product_domain(domain, resource, provider, product_id)
user.add_subscription_product_domain(domain, resource, provider, "prod_12345")

delete "/subscription-server/user-authorizations", params: { domain: domain }
expect(response.status).to eq(200)

user.reload
expect(user.custom_fields[user.subscription_product_domain_key(resource, provider, product_id)]).to eq("")
expect(user.custom_fields[user.subscription_product_domain_key(resource, provider, "prod_12345")]).to eq("")
end
end
end
end

0 comments on commit 7b778cb

Please sign in to comment.