Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/controllers/subscriptions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def index

def create
@subscription = current_user.subscriptions.build(subscription_params)
@subscription.space = current_space unless current_space.default?

if @subscription.save
flash[:notice] = t('subscriptions.created')
Expand Down
10 changes: 10 additions & 0 deletions app/models/space.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class Space < ApplicationRecord
has_many :collections, dependent: :nullify
has_many :learning_paths, dependent: :nullify
has_many :learning_path_topics, dependent: :nullify
has_many :subscriptions, dependent: :nullify
has_many :space_roles, dependent: :destroy
has_many :space_role_users, through: :space_roles, source: :user, class_name: 'User'
has_many :administrator_roles, -> { where(key: :admin) }, class_name: 'SpaceRole'
Expand All @@ -33,6 +34,15 @@ def self.current_space
Thread.current[:current_space] || Space.default
end

def self.with_current_space(space)
old_space = current_space
old_space = nil if old_space.default?
self.current_space = space
yield
ensure
self.current_space = old_space
end

def self.default
DefaultSpace.new
end
Expand Down
8 changes: 5 additions & 3 deletions app/models/subscription.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Subscription < ApplicationRecord
validates :subscribable_type, presence: true
validate :valid_subscribable_type
belongs_to :user
belongs_to :space, optional: true

before_create :set_last_checked_at

Expand All @@ -33,9 +34,10 @@ def valid_unsubscribe_code?(code)
end

def digest
type = subscribable_type.constantize

type.search_and_filter(user, query, facets_with_max_age, per_page: 15).results
Space.with_current_space(space) do
type = subscribable_type.constantize
type.search_and_filter(user, query, facets_with_max_age, per_page: 15).results
end
end

def facets_with_max_age
Expand Down
5 changes: 5 additions & 0 deletions db/migrate/20260417000001_add_space_id_to_subscriptions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddSpaceIdToSubscriptions < ActiveRecord::Migration[7.2]
def change
add_reference :subscriptions, :space, foreign_key: true
Comment thread
fbacall marked this conversation as resolved.
end
end
5 changes: 4 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

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

Expand Down Expand Up @@ -577,6 +577,8 @@
t.datetime "updated_at", null: false
t.string "subscribable_type"
t.datetime "last_checked_at"
t.bigint "space_id"
t.index ["space_id"], name: "index_subscriptions_on_space_id"
t.index ["user_id"], name: "index_subscriptions_on_user_id"
end

Expand Down Expand Up @@ -705,6 +707,7 @@
add_foreign_key "spaces", "users"
add_foreign_key "staff_members", "nodes"
add_foreign_key "stars", "users"
add_foreign_key "subscriptions", "spaces"
add_foreign_key "subscriptions", "users"
add_foreign_key "users", "roles"
add_foreign_key "workflows", "spaces"
Expand Down
16 changes: 16 additions & 0 deletions test/controllers/subscriptions_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,26 @@ class SubscriptionsControllerTest < ActionController::TestCase
assert_equal 'fish', assigns(:subscription).query
assert_equal ['country'], assigns(:subscription).facets.keys
assert_equal 'Finland', assigns(:subscription).facets['country']
assert_nil assigns(:subscription).space

assert_redirected_to subscriptions_path
end

test 'should create a new subscription scoped to the current space' do
with_host(spaces(:plants).host) do
sign_in users(:regular_user)
with_settings(feature: { 'spaces' => true }) do
assert_difference('Subscription.count') do
post :create, params: { subscription: { frequency: 'weekly', subscribable_type: 'Event' }, q: 'flowers' }
end
end

assert_equal spaces(:plants), assigns(:subscription).space

assert_redirected_to subscriptions_path
end
end

test 'should not include junk params in new subscription' do
sign_in users(:regular_user)

Expand Down
9 changes: 9 additions & 0 deletions test/fixtures/subscriptions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,12 @@ learning_path_subscription:
facets: { "type": [ "fruit", "veg" ] }
user: regular_user
subscribable_type: LearningPath

spaced_subscription:
frequency: 2
last_checked_at: 1986-11-23 10:16:33
query: plants
facets: {}
user: regular_user
subscribable_type: Material
space: plants
30 changes: 30 additions & 0 deletions test/models/space_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,34 @@ class SpaceTest < ActiveSupport::TestCase
refute @space.is_subdomain?
assert Space.new(host: 'test.example.com').is_subdomain?
end

test 'with_current_space' do
astro = spaces(:astro)
Space.current_space = astro
assert_equal astro, Space.current_space

# Sets space and reverts after
plants = spaces(:plants)
Space.with_current_space(plants) do
assert_equal plants, Space.current_space
end
assert_equal astro, Space.current_space

# Resets after exception
assert_raises(RuntimeError) do
Space.with_current_space(plants) do
raise 'oh no'
end
end
assert_equal astro, Space.current_space

# Handles nil and default spaces
Space.with_current_space(nil) do
assert Space.current_space.default?
end

Space.with_current_space(Space.default) do
assert Space.current_space.default?
end
end
end
31 changes: 31 additions & 0 deletions test/models/subscription_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,35 @@ class SubscriptionTest < ActiveSupport::TestCase
sub = subscriptions(:event_subscription)
assert_equal({ times: ["good", "great"], max_age: '1 week' }.with_indifferent_access, sub.facets_with_max_age)
end

test 'subscription can be scoped to a space' do
sub = subscriptions(:spaced_subscription)
assert_equal spaces(:plants), sub.space
end

test 'digest temporarily sets current space to subscription space' do
Space.current_space = spaces(:astro)
sub = subscriptions(:spaced_subscription)
captured_space = nil

type = sub.subscribable_type.constantize
type.stub(:search_and_filter, ->(*_args) { captured_space = Space.current_space; MockSearch.new([]) }) do
sub.digest
end

assert_equal spaces(:plants), captured_space
assert_equal spaces(:astro), Space.current_space
end

test 'digest restores current space even if search raises' do
Space.current_space = spaces(:astro)
sub = subscriptions(:spaced_subscription)

type = sub.subscribable_type.constantize
type.stub(:search_and_filter, ->(*_args) { raise 'boom' }) do
assert_raises(RuntimeError) { sub.digest }
end

assert_equal spaces(:astro), Space.current_space
end
end
Loading