Add Mongoid support with shared Core modules#908
Conversation
Co-authored-by: LTe <160962+LTe@users.noreply.github.com>
Co-authored-by: LTe <160962+LTe@users.noreply.github.com>
Co-authored-by: LTe <160962+LTe@users.noreply.github.com>
Co-authored-by: LTe <160962+LTe@users.noreply.github.com>
Co-authored-by: LTe <160962+LTe@users.noreply.github.com>
| @@ -0,0 +1,369 @@ | |||
| # typed: false | |||
There was a problem hiding this comment.
Specs in this file looks almost the same as in other file. I think we should have the same specs for both ActiveRecord and Monogoid and change only setup / teardown if needed.
There was a problem hiding this comment.
Refactored to use shared examples in spec/support/shared_examples.rb. Both ActiveRecord and Mongoid specs now include the same test cases via include_examples 'acts_as_messageable', adapter: :active_record/:mongoid, with only ORM-specific setup/teardown and adapter-specific tests in individual spec files. (b0f9b39)
There was a problem hiding this comment.
This was addressed in b0f9b39. The specs now use shared examples in spec/support/shared_examples.rb that both acts_as_messageable_spec.rb and mongoid_spec.rb include via include_examples 'acts_as_messageable', adapter: :active_record/:mongoid. Only ORM-specific tests remain in individual spec files.
Co-authored-by: LTe <160962+LTe@users.noreply.github.com>
spec/mongoid_spec.rb
Outdated
| describe 'ancestry functionality' do | ||
| let(:message) { ActsAsMessageable::Mongoid::Message.create!(topic: 'topic', body: 'body') } | ||
|
|
||
| it 'returns root of the conversation' do | ||
| expect(message.conversation).to include(message) | ||
| end | ||
|
|
||
| it 'handles parent assignment' do | ||
| parent_message = ActsAsMessageable::Mongoid::Message.create!(topic: 'parent', body: 'parent body') | ||
| child_message = ActsAsMessageable::Mongoid::Message.create!(topic: 'child', body: 'child body') | ||
| child_message.parent = parent_message | ||
| child_message.save! | ||
|
|
||
| expect(child_message.parent).to eq(parent_message) | ||
| expect(child_message.root).to eq(parent_message) | ||
| end | ||
|
|
||
| it 'handles subtree' do | ||
| parent_message = ActsAsMessageable::Mongoid::Message.create!(topic: 'parent', body: 'parent body') | ||
| child_message = ActsAsMessageable::Mongoid::Message.create!(topic: 'child', body: 'child body') | ||
| child_message.parent = parent_message | ||
| child_message.save! | ||
|
|
||
| expect(parent_message.subtree.to_a).to include(parent_message, child_message) | ||
| end | ||
| end |
There was a problem hiding this comment.
This is to specific, it should be tested between adapters and should be in shared behavior. We are testing gem here that provide tree structure.
There was a problem hiding this comment.
Moved tree structure tests to shared examples in spec/support/shared_examples.rb. The tests now run for both ActiveRecord and Mongoid adapters. (ae040cb)
| MONGOID_SPECS_ENABLED = ENV['MONGOID_SPECS'] == 'true' | ||
|
|
||
| if MONGOID_SPECS_ENABLED | ||
| require 'mongoid' | ||
| require 'acts_as_messageable/mongoid' | ||
|
|
||
| # Configure Mongoid for testing | ||
| Mongoid.configure do |config| | ||
| config.clients.default = { | ||
| hosts: [ENV.fetch('MONGODB_HOST', 'localhost:27017')], | ||
| database: 'acts_as_messageable_test' | ||
| } | ||
| config.log_level = :warn | ||
| end | ||
|
|
||
| # Include Mongoid model support | ||
| Mongoid::Document::ClassMethods.include ActsAsMessageable::Mongoid::Model | ||
| Mongoid::Criteria.include ActsAsMessageable::Mongoid::Relation | ||
|
|
||
| # Load Mongoid test models | ||
| require_relative 'support/mongoid_models' | ||
| end |
There was a problem hiding this comment.
Do we have github action that will run this?
There was a problem hiding this comment.
Added test-mongoid job to .github/workflows/test.yml that runs Mongoid specs with a MongoDB service container. (ae040cb)
| default_options = { | ||
| class_name: 'ActsAsMessageable::Mongoid::Message', | ||
| required: %i[topic body], | ||
| dependent: :nullify, | ||
| group_messages: false, | ||
| search_scope: :search | ||
| } | ||
| options = default_options.merge(options) | ||
|
|
||
| cattr_accessor(:messages_class_name, :group_messages) | ||
|
|
||
| has_many :received_messages_relation, | ||
| as: :received_messageable, | ||
| class_name: options[:class_name], | ||
| dependent: options[:dependent] | ||
| has_many :sent_messages_relation, | ||
| as: :sent_messageable, | ||
| class_name: options[:class_name], | ||
| dependent: options[:dependent] | ||
|
|
||
| self.messages_class_name = options[:class_name].constantize | ||
| messages_class_name.initialize_scopes(options[:search_scope]) | ||
|
|
||
| messages_class_name.required = Array.wrap(options[:required]) | ||
| messages_class_name.required.each do |attr| | ||
| messages_class_name.validates attr, presence: true | ||
| end | ||
| self.group_messages = options[:group_messages] |
There was a problem hiding this comment.
This part is almost identical to Active Record. Try harder with refactoring.
There was a problem hiding this comment.
Extracted shared ClassBehavior module in lib/acts_as_messageable/core/class_behavior.rb. The acts_as_messageable method now uses shared setup_messageable logic with adapter-specific messageable_default_options and define_messageable_associations methods. (ae040cb)
…mples, add Mongoid CI job Co-authored-by: LTe <160962+LTe@users.noreply.github.com>
| describe 'tree structure (ancestry)' do | ||
| let(:message_class) { adapter == :mongoid ? ActsAsMessageable::Mongoid::Message : ActsAsMessageable::Message } | ||
|
|
||
| before do | ||
| if adapter == :active_record | ||
| # Use clean version of Message class | ||
| ActsAsMessageable::Message.table_name = 'messages' | ||
| ActsAsMessageable::Message.required = [] | ||
| ActsAsMessageable::Message.clear_validators! if ActsAsMessageable::Message.respond_to?(:clear_validators!) | ||
| end | ||
| end | ||
|
|
||
| it 'returns root of the conversation' do | ||
| test_message = message_class.create!(topic: 'topic', body: 'body') | ||
| expect(test_message.conversation).to include(test_message) | ||
| end | ||
|
|
||
| it 'handles parent assignment' do | ||
| parent_message = message_class.create!(topic: 'parent', body: 'parent body') | ||
| child_message = message_class.create!(topic: 'child', body: 'child body') | ||
| child_message.parent = parent_message | ||
| child_message.save! | ||
|
|
||
| expect(child_message.parent).to eq(parent_message) | ||
| expect(child_message.root).to eq(parent_message) | ||
| end | ||
|
|
||
| it 'handles subtree' do | ||
| parent_message = message_class.create!(topic: 'parent', body: 'parent body') | ||
| child_message = message_class.create!(topic: 'child', body: 'child body') | ||
| child_message.parent = parent_message | ||
| child_message.save! | ||
|
|
||
| expect(parent_message.subtree.to_a).to include(parent_message, child_message) | ||
| end | ||
| end |
There was a problem hiding this comment.
This specs are to specific. We should send group message, reply to message and check if tree is right. Not modify parents and stuff
There was a problem hiding this comment.
Refactored tree structure tests to use the messaging API (send_message, reply_to) instead of low-level parent assignment. Tests now verify root, subtree, and conversation order through actual message replies. (8a656ad)
…el parent assignment Co-authored-by: LTe <160962+LTe@users.noreply.github.com>
Refactoring Mongoid support to reduce code duplication
Changes Made
mongoid-treegemMONGOID_SPECS=trueflagspec/support/shared_examples.rblib/acts_as_messageable/core/class_behavior.rb)test-mongoidjob with MongoDB servicesend_message,reply_toinstead of low-level parent assignmentTree Structure Tests (Revised)
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.