acts-as-messageable 0.4.11 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.dockerignore +1 -0
- data/.github/dependabot.yml +8 -0
- data/.github/workflows/test.yml +152 -0
- data/.rubocop.yml +32 -0
- data/.rubocop_todo.yml +75 -0
- data/.ruby-version +1 -0
- data/Appraisals +35 -11
- data/Dockerfile +14 -0
- data/Gemfile +22 -9
- data/Gemfile.lock +210 -90
- data/README.md +31 -14
- data/Rakefile +10 -1
- data/VERSION +1 -1
- data/acts-as-messageable.gemspec +225 -59
- data/bin/tapioca +29 -0
- data/docker-compose.yml +84 -0
- data/gemfiles/rails_3.2.gemfile +22 -10
- data/gemfiles/rails_4.2.gemfile +29 -0
- data/gemfiles/rails_5.2.gemfile +22 -10
- data/gemfiles/rails_6.0.gemfile +22 -10
- data/gemfiles/rails_7.0.gemfile +29 -0
- data/gemfiles/rails_master.gemfile +29 -0
- data/lib/acts-as-messageable.rb +3 -17
- data/lib/acts_as_messageable/message.rb +136 -0
- data/lib/acts_as_messageable/model.rb +229 -0
- data/lib/acts_as_messageable/rails3.rb +46 -0
- data/lib/acts_as_messageable/rails4.rb +54 -0
- data/lib/acts_as_messageable/rails6.rb +63 -0
- data/lib/acts_as_messageable/railtie.rb +12 -0
- data/lib/acts_as_messageable/relation.rb +35 -0
- data/lib/acts_as_messageable/scopes.rb +53 -0
- data/lib/acts_as_messageable.rb +41 -0
- data/lib/generators/acts_as_messageable/migration/migration_generator.rb +48 -0
- data/lib/generators/{acts-as-messageable → acts_as_messageable}/migration/templates/migration.rb +4 -3
- data/lib/generators/acts_as_messageable/migration/templates/migration_indexes.rb +12 -0
- data/lib/generators/acts_as_messageable/migration/templates/migration_opened_as_datetime.rb +16 -0
- data/lib/generators/{acts-as-messageable → acts_as_messageable}/migration/templates/migration_permanent.rb +2 -1
- data/sorbet/config +4 -0
- data/sorbet/rbi/annotations/actionpack.rbi +428 -0
- data/sorbet/rbi/annotations/actionview.rbi +77 -0
- data/sorbet/rbi/annotations/activerecord.rbi +18 -0
- data/sorbet/rbi/annotations/activesupport.rbi +52 -0
- data/sorbet/rbi/annotations/faraday.rbi +17 -0
- data/sorbet/rbi/annotations/railties.rbi +58 -0
- data/sorbet/rbi/annotations/rainbow.rbi +269 -0
- data/sorbet/rbi/dsl/abstract_controller/caching/fragments.rbi +23 -0
- data/sorbet/rbi/dsl/abstract_controller/caching.rbi +30 -0
- data/sorbet/rbi/dsl/abstract_controller/callbacks.rbi +23 -0
- data/sorbet/rbi/dsl/abstract_controller/helpers.rbi +23 -0
- data/sorbet/rbi/dsl/abstract_controller/rendering.rbi +9 -0
- data/sorbet/rbi/dsl/abstract_controller/url_for.rbi +23 -0
- data/sorbet/rbi/dsl/action_controller/caching.rbi +29 -0
- data/sorbet/rbi/dsl/action_controller/conditional_get.rbi +23 -0
- data/sorbet/rbi/dsl/action_controller/content_security_policy.rbi +31 -0
- data/sorbet/rbi/dsl/action_controller/data_streaming.rbi +9 -0
- data/sorbet/rbi/dsl/action_controller/etag_with_flash.rbi +24 -0
- data/sorbet/rbi/dsl/action_controller/etag_with_template_digest.rbi +30 -0
- data/sorbet/rbi/dsl/action_controller/flash.rbi +19 -0
- data/sorbet/rbi/dsl/action_controller/form_builder.rbi +19 -0
- data/sorbet/rbi/dsl/action_controller/helpers.rbi +36 -0
- data/sorbet/rbi/dsl/action_controller/params_wrapper.rbi +23 -0
- data/sorbet/rbi/dsl/action_controller/redirecting.rbi +24 -0
- data/sorbet/rbi/dsl/action_controller/renderers/all.rbi +24 -0
- data/sorbet/rbi/dsl/action_controller/renderers.rbi +23 -0
- data/sorbet/rbi/dsl/action_controller/request_forgery_protection.rbi +31 -0
- data/sorbet/rbi/dsl/action_controller/rescue.rbi +24 -0
- data/sorbet/rbi/dsl/action_controller/test_case/behavior.rbi +24 -0
- data/sorbet/rbi/dsl/action_controller/url_for.rbi +24 -0
- data/sorbet/rbi/dsl/action_dispatch/routing/url_for.rbi +23 -0
- data/sorbet/rbi/dsl/action_view/helpers/form_helper.rbi +10 -0
- data/sorbet/rbi/dsl/action_view/helpers/form_tag_helper.rbi +10 -0
- data/sorbet/rbi/dsl/action_view/helpers/text_helper.rbi +9 -0
- data/sorbet/rbi/dsl/action_view/helpers.rbi +10 -0
- data/sorbet/rbi/dsl/action_view/layouts.rbi +24 -0
- data/sorbet/rbi/dsl/action_view/rendering.rbi +9 -0
- data/sorbet/rbi/dsl/active_model/attribute_methods.rbi +27 -0
- data/sorbet/rbi/dsl/active_model/attributes.rbi +34 -0
- data/sorbet/rbi/dsl/active_model/dirty.rbi +28 -0
- data/sorbet/rbi/dsl/active_model/serializers/json.rbi +22 -0
- data/sorbet/rbi/dsl/active_model/validations/callbacks.rbi +22 -0
- data/sorbet/rbi/dsl/active_model/validations.rbi +27 -0
- data/sorbet/rbi/dsl/active_record/attribute_methods/dirty.rbi +38 -0
- data/sorbet/rbi/dsl/active_record/attribute_methods/time_zone_conversion.rbi +32 -0
- data/sorbet/rbi/dsl/active_record/attribute_methods.rbi +53 -0
- data/sorbet/rbi/dsl/active_record/attributes.rbi +19 -0
- data/sorbet/rbi/dsl/active_record/callbacks.rbi +22 -0
- data/sorbet/rbi/dsl/active_record/core.rbi +55 -0
- data/sorbet/rbi/dsl/active_record/encryption/encryptable_record.rbi +23 -0
- data/sorbet/rbi/dsl/active_record/inheritance.rbi +27 -0
- data/sorbet/rbi/dsl/active_record/integration.rbi +32 -0
- data/sorbet/rbi/dsl/active_record/locking/optimistic.rbi +22 -0
- data/sorbet/rbi/dsl/active_record/model_schema.rbi +52 -0
- data/sorbet/rbi/dsl/active_record/nested_attributes.rbi +22 -0
- data/sorbet/rbi/dsl/active_record/readonly_attributes.rbi +19 -0
- data/sorbet/rbi/dsl/active_record/reflection.rbi +32 -0
- data/sorbet/rbi/dsl/active_record/scoping/default.rbi +23 -0
- data/sorbet/rbi/dsl/active_record/scoping.rbi +23 -0
- data/sorbet/rbi/dsl/active_record/serialization.rbi +22 -0
- data/sorbet/rbi/dsl/active_record/signed_id.rbi +22 -0
- data/sorbet/rbi/dsl/active_record/test_fixtures.rbi +58 -0
- data/sorbet/rbi/dsl/active_record/timestamp.rbi +23 -0
- data/sorbet/rbi/dsl/active_record/validations.rbi +28 -0
- data/sorbet/rbi/dsl/active_support/actionable_error.rbi +23 -0
- data/sorbet/rbi/dsl/active_support/callbacks.rbi +22 -0
- data/sorbet/rbi/dsl/active_support/rescuable.rbi +23 -0
- data/sorbet/rbi/dsl/active_support/testing/file_fixtures.rbi +22 -0
- data/sorbet/rbi/gems/actionpack@7.0.4.3.rbi +19265 -0
- data/sorbet/rbi/gems/actionview@7.0.4.3.rbi +15482 -0
- data/sorbet/rbi/gems/activemodel@7.0.4.3.rbi +6025 -0
- data/sorbet/rbi/gems/activerecord@7.0.4.3.rbi +37852 -0
- data/sorbet/rbi/gems/activesupport@7.0.4.3.rbi +18788 -0
- data/sorbet/rbi/gems/addressable@2.4.0.rbi +8 -0
- data/sorbet/rbi/gems/appraisal@2.4.1.rbi +584 -0
- data/sorbet/rbi/gems/ast@2.4.2.rbi +584 -0
- data/sorbet/rbi/gems/builder@3.2.4.rbi +8 -0
- data/sorbet/rbi/gems/coderay@1.1.3.rbi +3426 -0
- data/sorbet/rbi/gems/commander@4.6.0.rbi +8 -0
- data/sorbet/rbi/gems/concurrent-ruby@1.2.2.rbi +11545 -0
- data/sorbet/rbi/gems/coveralls_reborn@0.27.0.rbi +8 -0
- data/sorbet/rbi/gems/crass@1.0.6.rbi +622 -0
- data/sorbet/rbi/gems/descendants_tracker@0.0.4.rbi +8 -0
- data/sorbet/rbi/gems/diff-lcs@1.5.0.rbi +1079 -0
- data/sorbet/rbi/gems/docile@1.4.0.rbi +8 -0
- data/sorbet/rbi/gems/erubi@1.12.0.rbi +146 -0
- data/sorbet/rbi/gems/faraday@0.9.2.rbi +964 -0
- data/sorbet/rbi/gems/git@1.11.0.rbi +2700 -0
- data/sorbet/rbi/gems/github_api@0.16.0.rbi +8 -0
- data/sorbet/rbi/gems/hashie@5.0.0.rbi +8 -0
- data/sorbet/rbi/gems/highline@2.0.3.rbi +8 -0
- data/sorbet/rbi/gems/i18n@1.12.0.rbi +2296 -0
- data/sorbet/rbi/gems/jeweler@2.3.9.rbi +1591 -0
- data/sorbet/rbi/gems/json@2.6.3.rbi +1541 -0
- data/sorbet/rbi/gems/jwt@2.5.0.rbi +8 -0
- data/sorbet/rbi/gems/loofah@2.19.1.rbi +904 -0
- data/sorbet/rbi/gems/method_source@1.0.0.rbi +272 -0
- data/sorbet/rbi/gems/mime-types@2.99.3.rbi +8 -0
- data/sorbet/rbi/gems/minitest@5.18.0.rbi +1491 -0
- data/sorbet/rbi/gems/multi_json@1.15.0.rbi +8 -0
- data/sorbet/rbi/gems/multi_xml@0.6.0.rbi +8 -0
- data/sorbet/rbi/gems/multipart-post@2.2.3.rbi +8 -0
- data/sorbet/rbi/gems/netrc@0.11.0.rbi +158 -0
- data/sorbet/rbi/gems/nokogiri@1.14.2.rbi +7244 -0
- data/sorbet/rbi/gems/oauth2@1.4.8.rbi +8 -0
- data/sorbet/rbi/gems/parallel@1.22.1.rbi +277 -0
- data/sorbet/rbi/gems/pg@1.4.6.rbi +2574 -0
- data/sorbet/rbi/gems/polyfill@1.9.0.rbi +8 -0
- data/sorbet/rbi/gems/pry@0.14.2.rbi +10081 -0
- data/sorbet/rbi/gems/psych@4.0.6.rbi +1819 -0
- data/sorbet/rbi/gems/racc@1.6.2.rbi +155 -0
- data/sorbet/rbi/gems/rack-test@2.0.2.rbi +943 -0
- data/sorbet/rbi/gems/rack@2.2.6.4.rbi +5659 -0
- data/sorbet/rbi/gems/rails-dom-testing@2.0.3.rbi +455 -0
- data/sorbet/rbi/gems/rails-html-sanitizer@1.5.0.rbi +685 -0
- data/sorbet/rbi/gems/railties@7.0.4.3.rbi +4553 -0
- data/sorbet/rbi/gems/rainbow@3.1.1.rbi +8 -0
- data/sorbet/rbi/gems/rake@13.0.6.rbi +2959 -0
- data/sorbet/rbi/gems/rbi@0.0.16.rbi +3008 -0
- data/sorbet/rbi/gems/rbs@2.8.0.rbi +8 -0
- data/sorbet/rbi/gems/rchardet@1.8.0.rbi +1078 -0
- data/sorbet/rbi/gems/rdoc@6.5.0.rbi +12441 -0
- data/sorbet/rbi/gems/regexp_parser@2.7.0.rbi +8 -0
- data/sorbet/rbi/gems/rexml@3.2.5.rbi +8 -0
- data/sorbet/rbi/gems/rspec-core@3.12.0.rbi +10798 -0
- data/sorbet/rbi/gems/rspec-expectations@3.12.0.rbi +8090 -0
- data/sorbet/rbi/gems/rspec-mocks@3.12.0.rbi +5296 -0
- data/sorbet/rbi/gems/rspec-support@3.12.0.rbi +1617 -0
- data/sorbet/rbi/gems/rspec@3.12.0.rbi +88 -0
- data/sorbet/rbi/gems/ruby-progressbar@1.13.0.rbi +8 -0
- data/sorbet/rbi/gems/safe_type@1.1.1.rbi +8 -0
- data/sorbet/rbi/gems/semver2@3.4.2.rbi +8 -0
- data/sorbet/rbi/gems/simplecov-html@0.12.3.rbi +8 -0
- data/sorbet/rbi/gems/simplecov@0.22.0.rbi +8 -0
- data/sorbet/rbi/gems/simplecov_json_formatter@0.1.4.rbi +8 -0
- data/sorbet/rbi/gems/sorbet-coerce@0.7.0.rbi +8 -0
- data/sorbet/rbi/gems/stringio@3.0.2.rbi +8 -0
- data/sorbet/rbi/gems/sync@0.5.0.rbi +8 -0
- data/sorbet/rbi/gems/term-ansicolor@1.7.1.rbi +8 -0
- data/sorbet/rbi/gems/thor@1.2.1.rbi +3956 -0
- data/sorbet/rbi/gems/thread_safe@0.3.6.rbi +8 -0
- data/sorbet/rbi/gems/timecop@0.9.6.rbi +361 -0
- data/sorbet/rbi/gems/tins@1.32.1.rbi +8 -0
- data/sorbet/rbi/gems/tzinfo@2.0.6.rbi +5917 -0
- data/sorbet/rbi/gems/unicode-display_width@2.4.2.rbi +8 -0
- data/sorbet/rbi/gems/unparser@0.6.7.rbi +4515 -0
- data/sorbet/rbi/gems/webrick@1.7.0.rbi +2553 -0
- data/sorbet/rbi/gems/yard@0.9.28.rbi +17954 -0
- data/sorbet/rbi/gems/zeitwerk@2.6.7.rbi +966 -0
- data/sorbet/rbi/models/acts-as-messageable/message.rbi +668 -0
- data/sorbet/rbi/models/acts-as-messageable/user.rbi +343 -0
- data/sorbet/rbi/rails-rbi/active_record_base.rbi +119 -0
- data/sorbet/rbi/rails-rbi/active_record_relation.rbi +180 -0
- data/sorbet/rbi/shims/activerecord.rbi +4 -0
- data/sorbet/rbi/shims/model.rbi +9 -0
- data/sorbet/tapioca/config.yml +10 -0
- data/sorbet/tapioca/pre_require.rb +5 -0
- data/sorbet/tapioca/require.rb +10 -0
- data/spec/{acts-as-messageable_spec.rb → acts_as_messageable_spec.rb} +80 -5
- data/spec/{custom-class_spec.rb → custom_class_spec.rb} +15 -5
- data/spec/{custom-required_spec.rb → custom_required_spec.rb} +10 -4
- data/spec/{group-messages_spec.rb → group_messages_spec.rb} +5 -2
- data/spec/migrations_spec.rb +76 -0
- data/spec/spec_helper.rb +44 -41
- data/spec/support/admin.rb +5 -0
- data/spec/support/custom_message.rb +8 -0
- data/spec/support/custom_message_uuid.rb +6 -0
- data/spec/support/custom_search_user.rb +8 -0
- data/spec/support/men.rb +7 -0
- data/spec/support/send_message.rb +10 -1
- data/spec/support/table_schema.rb +36 -0
- data/spec/support/user.rb +5 -3
- data/spec/support/uuid_user.rb +9 -0
- data/tasks/types.rake +46 -0
- metadata +371 -39
- data/.travis.yml +0 -19
- data/gemfiles/rails_3.2.gemfile.lock +0 -153
- data/gemfiles/rails_4.2.11.gemfile +0 -16
- data/gemfiles/rails_4.2.11.gemfile.lock +0 -157
- data/gemfiles/rails_5.2.gemfile.lock +0 -155
- data/gemfiles/rails_6.0.gemfile.lock +0 -155
- data/lib/acts-as-messageable/message.rb +0 -62
- data/lib/acts-as-messageable/model.rb +0 -181
- data/lib/acts-as-messageable/rails3.rb +0 -19
- data/lib/acts-as-messageable/rails4.rb +0 -23
- data/lib/acts-as-messageable/railtie.rb +0 -13
- data/lib/acts-as-messageable/relation.rb +0 -17
- data/lib/acts-as-messageable/scopes.rb +0 -38
- data/lib/generators/acts-as-messageable/migration/migration_generator.rb +0 -30
@@ -1,3 +1,6 @@
|
|
1
|
+
# typed: ignore
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
1
4
|
require 'spec_helper'
|
2
5
|
|
3
6
|
describe 'ActsAsMessageable' do
|
@@ -70,14 +73,14 @@ describe 'ActsAsMessageable' do
|
|
70
73
|
end
|
71
74
|
|
72
75
|
it 'alice should be able to reply to a message from bob to alice' do
|
73
|
-
@reply_message =
|
76
|
+
@reply_message = @alice.reply_to(@message, 'Re: Topic', 'Body')
|
74
77
|
expect(@reply_message).not_to be_nil
|
75
78
|
expect(@bob.messages.are_from(@alice).count).to eq(1)
|
76
79
|
expect(@alice.sent_messages.are_to(@bob).count).to eq(1)
|
77
80
|
end
|
78
81
|
|
79
82
|
it 'alice should be able to reply to a message using the message object' do
|
80
|
-
@reply_message =
|
83
|
+
@reply_message = @message.reply('Re: Topic', 'Body')
|
81
84
|
expect(@reply_message).not_to be_nil
|
82
85
|
expect(@bob.messages.are_from(@alice).count).to eq(1)
|
83
86
|
expect(@alice.sent_messages.are_to(@bob).count).to eq(1)
|
@@ -85,13 +88,13 @@ describe 'ActsAsMessageable' do
|
|
85
88
|
|
86
89
|
it 'bob try to add something to conversation' do
|
87
90
|
@reply_message = @bob.reply_to(@message, 'Oh, I Forget', '1+1=2')
|
88
|
-
expect(@reply_message.from).to
|
89
|
-
expect(@reply_message.to).to
|
91
|
+
expect(@reply_message.from).to eq(@message.from)
|
92
|
+
expect(@reply_message.to).to eq(@message.to)
|
90
93
|
end
|
91
94
|
|
92
95
|
it 'bob try to add something to conversation and should receive proper order' do
|
93
96
|
@reply_message = @bob.reply_to(@message, 'Oh, I Forget', '1+1=2')
|
94
|
-
@sec_message
|
97
|
+
@sec_message = @alice.reply_to(@message, 'Yeah, right', '1+1=3!')
|
95
98
|
|
96
99
|
expect(@message.conversation).to eq([@sec_message, @reply_message, @message])
|
97
100
|
end
|
@@ -148,6 +151,12 @@ describe 'ActsAsMessageable' do
|
|
148
151
|
expect(@alice.received_messages.count).to eq(1)
|
149
152
|
end
|
150
153
|
|
154
|
+
it 'bob should be able to restore message' do
|
155
|
+
@bob.sent_messages.process(&:delete)
|
156
|
+
@bob.restore_message(@message.reload)
|
157
|
+
expect(@bob.sent_messages.count).to eq(1)
|
158
|
+
end
|
159
|
+
|
151
160
|
it 'should works with relation' do
|
152
161
|
@alice.received_messages.process(&:delete)
|
153
162
|
expect(@alice.received_messages.count).to eq(0)
|
@@ -164,6 +173,7 @@ describe 'ActsAsMessageable' do
|
|
164
173
|
it 'alice should have one unread message from bob' do
|
165
174
|
expect(@alice.messages.are_from(@bob).unreaded.count).to eq(1)
|
166
175
|
expect(@alice.messages.are_from(@bob).readed.count).to eq(0)
|
176
|
+
expect(@alice.messages.are_from(@bob).readed.all?(&:open?)).to be_truthy
|
167
177
|
end
|
168
178
|
|
169
179
|
it 'alice should able to read message from bob' do
|
@@ -177,11 +187,33 @@ describe 'ActsAsMessageable' do
|
|
177
187
|
expect(@alice.messages.are_from(@bob).unreaded.count).to eq(1)
|
178
188
|
end
|
179
189
|
|
190
|
+
it 'alice should see the read_at updated' do
|
191
|
+
date_time_when_read = Time.new(2014, 9, 4, 15, 12, 34)
|
192
|
+
Timecop.freeze(date_time_when_read) do
|
193
|
+
@alice.messages.are_from(@bob).first.read
|
194
|
+
first_message = @alice.messages.are_from(@bob).first
|
195
|
+
expect(first_message.opened_at).to eql(date_time_when_read)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
180
199
|
it 'alice should able to get datetime when he read bob message' do
|
181
200
|
@alice.messages.are_from(@bob).first.read
|
182
201
|
read_datetime = @alice.messages.are_from(@bob).first.updated_at
|
183
202
|
expect(@alice.messages.are_from(@bob).reorder('updated_at asc').first.updated_at).to eq(read_datetime)
|
184
203
|
end
|
204
|
+
|
205
|
+
describe '#open?' do
|
206
|
+
let(:message) { @alice.messages.are_from(@bob).first }
|
207
|
+
|
208
|
+
it 'returns false for closed message' do
|
209
|
+
expect(message.open?).to be_falsey
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'returns true for open message' do
|
213
|
+
message.read
|
214
|
+
expect(message.open?).to be_truthy
|
215
|
+
end
|
216
|
+
end
|
185
217
|
end
|
186
218
|
|
187
219
|
it 'finds proper message' do
|
@@ -268,6 +300,10 @@ describe 'ActsAsMessageable' do
|
|
268
300
|
expect(@bob.sent_messages.loaded?).to be_falsey
|
269
301
|
end
|
270
302
|
|
303
|
+
it 'sent_messages should return unloaded messages' do
|
304
|
+
expect(@bob.sent_messages.loaded?).to be_falsey
|
305
|
+
end
|
306
|
+
|
271
307
|
describe 'send messages between two different models (the same id)' do
|
272
308
|
it 'should have the same id' do
|
273
309
|
expect(@alice.id).to be_equal(@admin.id)
|
@@ -285,4 +321,43 @@ describe 'ActsAsMessageable' do
|
|
285
321
|
expect(@bob.messages.are_from(@alice).size).to be_equal(0)
|
286
322
|
end
|
287
323
|
end
|
324
|
+
|
325
|
+
describe 'mass assigment', rails: 4 do
|
326
|
+
it 'allows to mass assign topic and body attributes' do
|
327
|
+
@message = send_message(@bob, @alice, 'Example', 'Example Body')
|
328
|
+
@message.update_attributes!(topic: 'Changed topic', body: 'Changed body')
|
329
|
+
|
330
|
+
expect(@message.topic).to eq('Changed topic')
|
331
|
+
expect(@message.body).to eq('Changed body')
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
describe 'ancestry initialization' do # GH#78
|
336
|
+
let(:message) { ActsAsMessageable::Message.create!(topic: 'topic', body: 'body') }
|
337
|
+
|
338
|
+
before do
|
339
|
+
# Use clean version of Message class we used here remove_const before
|
340
|
+
# but it doesn't work with sorbet so we use this hack to clear side effects
|
341
|
+
ActsAsMessageable::Message.table_name = 'messages'
|
342
|
+
ActsAsMessageable::Message.required = []
|
343
|
+
ActsAsMessageable::Message.clear_validators! if ActsAsMessageable::Message.respond_to?(:clear_validators!)
|
344
|
+
end
|
345
|
+
|
346
|
+
it 'returns root of the conversation' do
|
347
|
+
expect(message.conversation).to include(message)
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
describe 'user primary key is uuid type', rails: [5, 6, 7] do # GH#107
|
352
|
+
let(:bob) { UuidUser.create(id: SecureRandom.uuid, email: 'bob@example.com') }
|
353
|
+
let(:alice) { UuidUser.create(id: SecureRandom.uuid, email: 'alice@example.com') }
|
354
|
+
|
355
|
+
before do
|
356
|
+
bob.send_message(alice, 'Subject', 'Body')
|
357
|
+
end
|
358
|
+
|
359
|
+
it 'returns messages for alice' do
|
360
|
+
expect(alice.messages).not_to be_empty
|
361
|
+
end
|
362
|
+
end
|
288
363
|
end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
|
1
|
+
# typed: ignore
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
|
4
|
-
def custom_method; end
|
5
|
-
end
|
4
|
+
require 'spec_helper'
|
6
5
|
|
7
6
|
describe 'custom class' do
|
8
7
|
let(:alice) { User.find_by_email('alice@example.com') }
|
9
|
-
let(:bob)
|
8
|
+
let(:bob) { User.find_by_email('bob@example.com') }
|
9
|
+
let(:custom_user) { CustomSearchUser.find_by_email('custom@example.com') }
|
10
10
|
|
11
11
|
before do
|
12
12
|
User.acts_as_messageable class_name: 'CustomMessage', table_name: 'custom_messages'
|
@@ -36,4 +36,14 @@ describe 'custom class' do
|
|
36
36
|
expect(@reply_message.root).to eq(@message)
|
37
37
|
expect(@reply_message.root.class).to eq(CustomMessage)
|
38
38
|
end
|
39
|
+
|
40
|
+
context 'with custom search scope' do
|
41
|
+
before do
|
42
|
+
send_message(custom_user, bob, 'Test subject', 'Test body')
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'will use custom search scope' do
|
46
|
+
expect(custom_user.messages.custom_search('Test body').count).to eq(1)
|
47
|
+
end
|
48
|
+
end
|
39
49
|
end
|
@@ -1,10 +1,16 @@
|
|
1
|
+
# typed: ignore
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
1
4
|
require 'spec_helper'
|
2
5
|
|
3
6
|
describe 'custom require' do
|
4
|
-
before
|
5
|
-
# Use clean version of Message class
|
6
|
-
|
7
|
-
|
7
|
+
before do
|
8
|
+
# Use clean version of Message class we used here remove_const before
|
9
|
+
# but it doesn't work with sorbet so we use this hack to clear side effects
|
10
|
+
ActsAsMessageable::Message.table_name = 'messages'
|
11
|
+
ActsAsMessageable::Message.required = []
|
12
|
+
ActsAsMessageable::Message.clear_validators! if ActsAsMessageable::Message.respond_to?(:clear_validators!)
|
13
|
+
ActsAsMessageable::Message.reset_callbacks(:validate)
|
8
14
|
end
|
9
15
|
|
10
16
|
it 'should work with non-array require' do
|
@@ -1,9 +1,12 @@
|
|
1
|
+
# typed: ignore
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
1
4
|
require 'spec_helper'
|
2
5
|
|
3
6
|
describe 'group messages' do
|
4
7
|
let(:alice) { User.find_by_email('alice@example.com') }
|
5
|
-
let(:bob)
|
6
|
-
let(:pat)
|
8
|
+
let(:bob) { User.find_by_email('bob@example.com') }
|
9
|
+
let(:pat) { User.find_by_email('pat@example.com') }
|
7
10
|
|
8
11
|
before do
|
9
12
|
User.acts_as_messageable group_messages: true
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# typed: ignore
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
|
6
|
+
def create_dummy_app
|
7
|
+
system <<-COMMAND
|
8
|
+
bundle exec rails new dummy --skip-test-unit --skip-spring --skip-webpack-install --skip-bootsnap \
|
9
|
+
--skip-active-storage --skip-active-job --skip-action-cable --skip-javascript --skip-action-mailer -d sqlite3
|
10
|
+
COMMAND
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_gem_to_gemfile
|
14
|
+
run_in_app("echo gem \"'acts-as-messageable', path: '../'\" >> Gemfile; bundle")
|
15
|
+
end
|
16
|
+
|
17
|
+
def run_bundler
|
18
|
+
run_in_app('bundle update')
|
19
|
+
end
|
20
|
+
|
21
|
+
def run_generators(option = '')
|
22
|
+
run_in_app("bundle exec rails g acts_as_messageable:migration #{option}")
|
23
|
+
end
|
24
|
+
|
25
|
+
def run_migrations
|
26
|
+
run_in_app('bundle exec rake db:migrate')
|
27
|
+
end
|
28
|
+
|
29
|
+
def rollback_migrations
|
30
|
+
run_in_app('bundle exec rake db:migrate VERSION=0')
|
31
|
+
end
|
32
|
+
|
33
|
+
def run_in_app(command)
|
34
|
+
Bundler.clean_system("cd dummy; BUNDLE_GEMFILE=./Gemfile #{command}")
|
35
|
+
end
|
36
|
+
|
37
|
+
def remove_dummy_app
|
38
|
+
system 'rm -rf dummy'
|
39
|
+
end
|
40
|
+
|
41
|
+
def skip_generators?
|
42
|
+
ENV.fetch('RUN_GENERATORS', 'false') == 'false'
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'migration' do
|
46
|
+
before do
|
47
|
+
create_dummy_app
|
48
|
+
add_gem_to_gemfile
|
49
|
+
run_bundler
|
50
|
+
end
|
51
|
+
|
52
|
+
after do
|
53
|
+
remove_dummy_app
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'runs migrations and revert them', skip: skip_generators? do
|
57
|
+
run_generators
|
58
|
+
|
59
|
+
expect(run_migrations).to be_truthy
|
60
|
+
expect(rollback_migrations).to be_truthy
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'runs migrations and revert them with uuid option', skip: skip_generators? do
|
64
|
+
run_generators('--uuid')
|
65
|
+
|
66
|
+
expect(run_migrations).to be_truthy
|
67
|
+
expect(rollback_migrations).to be_truthy
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'runs migrations and revert them with uuid option and custom table', skip: skip_generators? do
|
71
|
+
run_generators('my_messages --uuid')
|
72
|
+
|
73
|
+
expect(run_migrations).to be_truthy
|
74
|
+
expect(rollback_migrations).to be_truthy
|
75
|
+
end
|
76
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,32 +1,43 @@
|
|
1
|
+
# typed: ignore
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'sorbet-runtime'
|
5
|
+
T::Configuration.default_checked_level = :tests
|
6
|
+
T::Configuration.enable_checking_for_sigs_marked_checked_tests
|
7
|
+
|
1
8
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
9
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
10
|
require 'rspec'
|
4
11
|
require 'active_record/railtie'
|
5
|
-
ActiveRecord::Base.logger = Logger.new(
|
12
|
+
ActiveRecord::Base.logger = Logger.new($stderr)
|
6
13
|
ActiveRecord::Base.logger.level = 3
|
7
14
|
|
8
15
|
require 'coveralls'
|
9
16
|
Coveralls.wear!
|
10
17
|
|
18
|
+
require 'timecop'
|
19
|
+
|
11
20
|
require 'bundler/setup'
|
12
21
|
Bundler.require(:default)
|
13
22
|
|
23
|
+
require 'pry'
|
14
24
|
require 'acts-as-messageable'
|
15
25
|
|
16
|
-
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
26
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].sort.each { |f| require f }
|
17
27
|
|
18
28
|
ActiveRecord::Migration.verbose = false
|
19
29
|
|
20
30
|
RSpec.configure do |config|
|
21
31
|
config.before(:all) do
|
22
|
-
|
32
|
+
establish_connection
|
23
33
|
create_database
|
24
34
|
|
25
|
-
@alice = User.create
|
26
|
-
@bob
|
27
|
-
@pat
|
35
|
+
@alice = User.create email: 'alice@example.com'
|
36
|
+
@bob = User.create email: 'bob@example.com'
|
37
|
+
@pat = User.create email: 'pat@example.com'
|
28
38
|
@admin = Admin.create email: 'admin@example.com'
|
29
|
-
@men
|
39
|
+
@men = Men.create email: 'men@example.com'
|
40
|
+
@custom_search_user = CustomSearchUser.create email: 'custom@example.com'
|
30
41
|
end
|
31
42
|
|
32
43
|
config.after(:all) do
|
@@ -36,44 +47,36 @@ RSpec.configure do |config|
|
|
36
47
|
config.after(:each) do
|
37
48
|
User.messages_class_name.destroy_all
|
38
49
|
end
|
50
|
+
|
51
|
+
config.around(:each) do |example|
|
52
|
+
supported_rails = Array.wrap(example.metadata[:rails]).presence || [3, 4, 5, 6, 7]
|
53
|
+
|
54
|
+
example.run if supported_rails.include?(Rails::VERSION::MAJOR)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def establish_connection
|
59
|
+
ActiveRecord::Base.establish_connection(
|
60
|
+
adapter: ENV.fetch('DATABASE_ADAPTER', 'sqlite3'),
|
61
|
+
database: ENV.fetch('DATABASE_NAME', ':memory:'),
|
62
|
+
password: ENV.fetch('DATABASE_PASSWORD', 'password'),
|
63
|
+
host: 'localhost',
|
64
|
+
user: 'postgres'
|
65
|
+
)
|
39
66
|
end
|
40
67
|
|
41
68
|
def create_database
|
42
69
|
ActiveRecord::Schema.define(version: 1) do
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
t.string :ancestry
|
54
|
-
t.timestamps
|
55
|
-
end
|
56
|
-
|
57
|
-
create_table :custom_messages do |t|
|
58
|
-
t.string :topic
|
59
|
-
t.text :body
|
60
|
-
t.references :received_messageable, polymorphic: true, index: false
|
61
|
-
t.references :sent_messageable, polymorphic: true, index: false
|
62
|
-
t.boolean :opened, default: false
|
63
|
-
t.boolean :recipient_delete, default: false
|
64
|
-
t.boolean :sender_delete, default: false
|
65
|
-
t.boolean :recipient_permanent_delete, default: false
|
66
|
-
t.boolean :sender_permanent_delete, default: false
|
67
|
-
t.string :ancestry
|
68
|
-
t.timestamps
|
69
|
-
end
|
70
|
-
create_table :users do |t|
|
71
|
-
t.string :email
|
72
|
-
end
|
73
|
-
|
74
|
-
create_table :admins do |t|
|
75
|
-
t.string :email
|
76
|
-
end
|
70
|
+
enable_extension 'pgcrypto' if ENV.fetch('DATABASE_ADAPTER', '') == 'postgresql' && !extension_enabled?('pgcrypto')
|
71
|
+
|
72
|
+
create_table(:messages, &TABLE_SCHEMA)
|
73
|
+
create_table(:custom_messages, &TABLE_SCHEMA)
|
74
|
+
create_table(:custom_messages_uuid, &TABLE_SCHEMA_UUID)
|
75
|
+
|
76
|
+
create_table(:users, &USER_SCHEMA)
|
77
|
+
create_table(:admins, &USER_SCHEMA)
|
78
|
+
create_table(:custom_search_users, &USER_SCHEMA)
|
79
|
+
create_table(:uuid_users, id: :uuid, &USER_SCHEMA)
|
77
80
|
end
|
78
81
|
end
|
79
82
|
|
data/spec/support/admin.rb
CHANGED
data/spec/support/men.rb
ADDED
@@ -1,3 +1,12 @@
|
|
1
|
-
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
extend T::Sig
|
5
|
+
|
6
|
+
sig do
|
7
|
+
params(from: ActiveRecord::Base, to: ActiveRecord::Base, topic: String,
|
8
|
+
body: String).returns(ActsAsMessageable::Message)
|
9
|
+
end
|
10
|
+
def send_message(from = T.unsafe(@bob), to = T.unsafe(@alice), topic = 'Topic', body = 'Body')
|
2
11
|
from.send_message(to, topic, body)
|
3
12
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
TABLE_SCHEMA = T.let(lambda do |t|
|
5
|
+
t.string :topic
|
6
|
+
t.text :body
|
7
|
+
t.references :received_messageable, polymorphic: true, index: false
|
8
|
+
t.references :sent_messageable, polymorphic: true, index: false
|
9
|
+
t.boolean :opened, default: false
|
10
|
+
t.boolean :recipient_delete, default: false
|
11
|
+
t.boolean :sender_delete, default: false
|
12
|
+
t.boolean :recipient_permanent_delete, default: false
|
13
|
+
t.boolean :sender_permanent_delete, default: false
|
14
|
+
t.datetime :opened_at, :datetime
|
15
|
+
t.string :ancestry
|
16
|
+
t.timestamps
|
17
|
+
end, T.untyped)
|
18
|
+
|
19
|
+
TABLE_SCHEMA_UUID = T.let(lambda do |t|
|
20
|
+
t.string :topic
|
21
|
+
t.text :body
|
22
|
+
t.references :received_messageable, polymorphic: true, index: false, type: :uuid
|
23
|
+
t.references :sent_messageable, polymorphic: true, index: false, type: :uuid
|
24
|
+
t.boolean :opened, default: false
|
25
|
+
t.boolean :recipient_delete, default: false
|
26
|
+
t.boolean :sender_delete, default: false
|
27
|
+
t.boolean :recipient_permanent_delete, default: false
|
28
|
+
t.boolean :sender_permanent_delete, default: false
|
29
|
+
t.datetime :opened_at, :datetime
|
30
|
+
t.string :ancestry
|
31
|
+
t.timestamps
|
32
|
+
end, T.untyped)
|
33
|
+
|
34
|
+
USER_SCHEMA = T.let(lambda do |t|
|
35
|
+
t.string :email
|
36
|
+
end, T.untyped)
|
data/spec/support/user.rb
CHANGED
@@ -0,0 +1,9 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
class UuidUser < ActiveRecord::Base
|
5
|
+
extend ActsAsMessageable::Model::ClassMethods
|
6
|
+
|
7
|
+
acts_as_messageable class_name: 'CustomMessageUUID', table_name: 'custom_messages_uuid'
|
8
|
+
self.table_name = :uuid_users
|
9
|
+
end
|
data/tasks/types.rake
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# typed: ignore
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
def generate_type(model, model_name, file_name)
|
5
|
+
establish_connection
|
6
|
+
create_database
|
7
|
+
|
8
|
+
formatter = SorbetRails::ModelRbiFormatter.new(model, Set.new([model_name]))
|
9
|
+
file_path = File.expand_path("../sorbet/rbi/models/acts-as-messageable/#{file_name}.rbi", __dir__)
|
10
|
+
FileUtils.mkdir_p(File.dirname(file_path))
|
11
|
+
File.write(file_path, formatter.generate_rbi)
|
12
|
+
|
13
|
+
drop_database
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate_types_for_active_record_runtime
|
17
|
+
establish_connection
|
18
|
+
create_database
|
19
|
+
|
20
|
+
dir_path = File.expand_path('../sorbet/rbi/rails-rbi/', __dir__)
|
21
|
+
FileUtils.mkdir_p(dir_path)
|
22
|
+
|
23
|
+
formatter = SorbetRails::ActiveRecordRbiFormatter.new
|
24
|
+
|
25
|
+
file_path = File.expand_path('../sorbet/rbi/rails-rbi/active_record_base.rbi', __dir__)
|
26
|
+
File.write(file_path, formatter.generate_active_record_base_rbi)
|
27
|
+
|
28
|
+
file_path = File.expand_path('../sorbet/rbi/rails-rbi/active_record_relation.rbi', __dir__)
|
29
|
+
File.write(file_path, formatter.generate_active_record_relation_rbi)
|
30
|
+
|
31
|
+
drop_database
|
32
|
+
end
|
33
|
+
|
34
|
+
desc 'Generate types for model'
|
35
|
+
task :generate_rbi_for_model do
|
36
|
+
require_relative '../spec/spec_helper'
|
37
|
+
require 'active_support/core_ext/string'
|
38
|
+
require 'sorbet-rails'
|
39
|
+
require 'sorbet-rails/active_record_rbi_formatter'
|
40
|
+
|
41
|
+
SorbetRails.configure {} # rubocop:disable Lint/EmptyBlock
|
42
|
+
|
43
|
+
generate_type(ActsAsMessageable::Message, 'ActsAsMessageable::Message', 'message')
|
44
|
+
generate_type(CustomSearchUser, 'CustomSearchUser', 'user')
|
45
|
+
generate_types_for_active_record_runtime
|
46
|
+
end
|