Skip to content

Commit fd3d3b7

Browse files
authored
Merge pull request #1284 from ElixirTeSS/copilot/add-space-id-field-to-subscriptions
Scope subscriptions to spaces
2 parents 7711496 + ef3804c commit fd3d3b7

9 files changed

Lines changed: 111 additions & 4 deletions

File tree

app/controllers/subscriptions_controller.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ def index
1212

1313
def create
1414
@subscription = current_user.subscriptions.build(subscription_params)
15+
@subscription.space = current_space unless current_space.default?
1516

1617
if @subscription.save
1718
flash[:notice] = t('subscriptions.created')

app/models/space.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class Space < ApplicationRecord
1111
has_many :collections, dependent: :nullify
1212
has_many :learning_paths, dependent: :nullify
1313
has_many :learning_path_topics, dependent: :nullify
14+
has_many :subscriptions, dependent: :nullify
1415
has_many :space_roles, dependent: :destroy
1516
has_many :space_role_users, through: :space_roles, source: :user, class_name: 'User'
1617
has_many :administrator_roles, -> { where(key: :admin) }, class_name: 'SpaceRole'
@@ -33,6 +34,15 @@ def self.current_space
3334
Thread.current[:current_space] || Space.default
3435
end
3536

37+
def self.with_current_space(space)
38+
old_space = current_space
39+
old_space = nil if old_space.default?
40+
self.current_space = space
41+
yield
42+
ensure
43+
self.current_space = old_space
44+
end
45+
3646
def self.default
3747
DefaultSpace.new
3848
end

app/models/subscription.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class Subscription < ApplicationRecord
1313
validates :subscribable_type, presence: true
1414
validate :valid_subscribable_type
1515
belongs_to :user
16+
belongs_to :space, optional: true
1617

1718
before_create :set_last_checked_at
1819

@@ -33,9 +34,10 @@ def valid_unsubscribe_code?(code)
3334
end
3435

3536
def digest
36-
type = subscribable_type.constantize
37-
38-
type.search_and_filter(user, query, facets_with_max_age, per_page: 15).results
37+
Space.with_current_space(space) do
38+
type = subscribable_type.constantize
39+
type.search_and_filter(user, query, facets_with_max_age, per_page: 15).results
40+
end
3941
end
4042

4143
def facets_with_max_age
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class AddSpaceIdToSubscriptions < ActiveRecord::Migration[7.2]
2+
def change
3+
add_reference :subscriptions, :space, foreign_key: true
4+
end
5+
end

db/schema.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema[7.2].define(version: 2026_03_10_163512) do
13+
ActiveRecord::Schema[7.2].define(version: 2026_04_17_000001) do
1414
# These are extensions that must be enabled in order to support this database
1515
enable_extension "plpgsql"
1616

@@ -577,6 +577,8 @@
577577
t.datetime "updated_at", null: false
578578
t.string "subscribable_type"
579579
t.datetime "last_checked_at"
580+
t.bigint "space_id"
581+
t.index ["space_id"], name: "index_subscriptions_on_space_id"
580582
t.index ["user_id"], name: "index_subscriptions_on_user_id"
581583
end
582584

@@ -705,6 +707,7 @@
705707
add_foreign_key "spaces", "users"
706708
add_foreign_key "staff_members", "nodes"
707709
add_foreign_key "stars", "users"
710+
add_foreign_key "subscriptions", "spaces"
708711
add_foreign_key "subscriptions", "users"
709712
add_foreign_key "users", "roles"
710713
add_foreign_key "workflows", "spaces"

test/controllers/subscriptions_controller_test.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,26 @@ class SubscriptionsControllerTest < ActionController::TestCase
3737
assert_equal 'fish', assigns(:subscription).query
3838
assert_equal ['country'], assigns(:subscription).facets.keys
3939
assert_equal 'Finland', assigns(:subscription).facets['country']
40+
assert_nil assigns(:subscription).space
4041

4142
assert_redirected_to subscriptions_path
4243
end
4344

45+
test 'should create a new subscription scoped to the current space' do
46+
with_host(spaces(:plants).host) do
47+
sign_in users(:regular_user)
48+
with_settings(feature: { 'spaces' => true }) do
49+
assert_difference('Subscription.count') do
50+
post :create, params: { subscription: { frequency: 'weekly', subscribable_type: 'Event' }, q: 'flowers' }
51+
end
52+
end
53+
54+
assert_equal spaces(:plants), assigns(:subscription).space
55+
56+
assert_redirected_to subscriptions_path
57+
end
58+
end
59+
4460
test 'should not include junk params in new subscription' do
4561
sign_in users(:regular_user)
4662

test/fixtures/subscriptions.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,12 @@ learning_path_subscription:
4040
facets: { "type": [ "fruit", "veg" ] }
4141
user: regular_user
4242
subscribable_type: LearningPath
43+
44+
spaced_subscription:
45+
frequency: 2
46+
last_checked_at: 1986-11-23 10:16:33
47+
query: plants
48+
facets: {}
49+
user: regular_user
50+
subscribable_type: Material
51+
space: plants

test/models/space_test.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,34 @@ class SpaceTest < ActiveSupport::TestCase
174174
refute @space.is_subdomain?
175175
assert Space.new(host: 'test.example.com').is_subdomain?
176176
end
177+
178+
test 'with_current_space' do
179+
astro = spaces(:astro)
180+
Space.current_space = astro
181+
assert_equal astro, Space.current_space
182+
183+
# Sets space and reverts after
184+
plants = spaces(:plants)
185+
Space.with_current_space(plants) do
186+
assert_equal plants, Space.current_space
187+
end
188+
assert_equal astro, Space.current_space
189+
190+
# Resets after exception
191+
assert_raises(RuntimeError) do
192+
Space.with_current_space(plants) do
193+
raise 'oh no'
194+
end
195+
end
196+
assert_equal astro, Space.current_space
197+
198+
# Handles nil and default spaces
199+
Space.with_current_space(nil) do
200+
assert Space.current_space.default?
201+
end
202+
203+
Space.with_current_space(Space.default) do
204+
assert Space.current_space.default?
205+
end
206+
end
177207
end

test/models/subscription_test.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,35 @@ class SubscriptionTest < ActiveSupport::TestCase
172172
sub = subscriptions(:event_subscription)
173173
assert_equal({ times: ["good", "great"], max_age: '1 week' }.with_indifferent_access, sub.facets_with_max_age)
174174
end
175+
176+
test 'subscription can be scoped to a space' do
177+
sub = subscriptions(:spaced_subscription)
178+
assert_equal spaces(:plants), sub.space
179+
end
180+
181+
test 'digest temporarily sets current space to subscription space' do
182+
Space.current_space = spaces(:astro)
183+
sub = subscriptions(:spaced_subscription)
184+
captured_space = nil
185+
186+
type = sub.subscribable_type.constantize
187+
type.stub(:search_and_filter, ->(*_args) { captured_space = Space.current_space; MockSearch.new([]) }) do
188+
sub.digest
189+
end
190+
191+
assert_equal spaces(:plants), captured_space
192+
assert_equal spaces(:astro), Space.current_space
193+
end
194+
195+
test 'digest restores current space even if search raises' do
196+
Space.current_space = spaces(:astro)
197+
sub = subscriptions(:spaced_subscription)
198+
199+
type = sub.subscribable_type.constantize
200+
type.stub(:search_and_filter, ->(*_args) { raise 'boom' }) do
201+
assert_raises(RuntimeError) { sub.digest }
202+
end
203+
204+
assert_equal spaces(:astro), Space.current_space
205+
end
175206
end

0 commit comments

Comments
 (0)