chatbox 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rspec +0 -1
- data/.travis.yml +2 -0
- data/README.md +4 -0
- data/chatbox.gemspec +1 -0
- data/lib/chatbox/draft.rb +12 -7
- data/lib/chatbox/inbox.rb +5 -1
- data/lib/chatbox/memcached_store.rb +93 -0
- data/lib/chatbox/memory_store.rb +40 -8
- data/lib/chatbox/message.rb +36 -0
- data/lib/chatbox/outbox.rb +6 -2
- data/lib/chatbox/version.rb +1 -1
- data/spec/chatbox_spec.rb +2 -26
- data/spec/integration_spec.rb +73 -0
- data/spec/lib/draft_spec.rb +8 -1
- data/spec/spec_helper.rb +6 -0
- metadata +20 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b66ba083f1d159cc4e17b4006dfc9890501b5a8
|
4
|
+
data.tar.gz: efdf4191ca17f8f92a5820efe735df7f39bbc888
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77bffe68cca61f58b1f0d177d3f5db898382c02030513a843f60f43cd5d3d8b854dca0d7140cfd34f13ed2f1ee7972f52f7e36af0c9b1aa1b1101f08a97e4997
|
7
|
+
data.tar.gz: 80f8b7d68f4c4bbcd38f29947440a805f59e46b68f2d47656e85f4a7b7b77d01d66f97fbee88e3cf27153d42fde073768b5e2f62654805aba1084f147f78a935
|
data/.rspec
CHANGED
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
[](http://badge.fury.io/rb/chatbox)
|
2
|
+
[](https://travis-ci.org/austinthecoder/chatbox)
|
3
|
+
[](https://codeclimate.com/github/austinthecoder/chatbox)
|
4
|
+
|
1
5
|
# Chatbox
|
2
6
|
|
3
7
|
Simple messaging system.
|
data/chatbox.gemspec
CHANGED
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency 'bundler', '~> 1.7'
|
22
22
|
spec.add_development_dependency 'rake', '~> 10.0'
|
23
23
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
24
|
+
spec.add_development_dependency 'dalli', '~> 2.7'
|
24
25
|
|
25
26
|
spec.add_dependency 'activesupport', '>= 3'
|
26
27
|
end
|
data/lib/chatbox/draft.rb
CHANGED
@@ -1,24 +1,29 @@
|
|
1
|
+
require 'securerandom'
|
1
2
|
require 'chatbox/fake_missing_keywords'
|
2
3
|
|
3
4
|
module Chatbox
|
4
5
|
class Draft
|
5
6
|
include FakeMissingKeywords
|
6
7
|
|
7
|
-
def initialize(from: req(:from), to: req(:to), body: req(:body), store: req(:store))
|
8
|
-
@
|
9
|
-
@
|
8
|
+
def initialize(from: req(:from), to: req(:to), body: req(:body), store: req(:store), id_generator: -> { SecureRandom.uuid })
|
9
|
+
@from = from
|
10
|
+
@to = to
|
10
11
|
@body = body
|
11
12
|
@store = store
|
13
|
+
@id_generator = id_generator
|
12
14
|
end
|
13
15
|
|
14
|
-
attr_reader :to_id, :from_id, :body
|
15
|
-
|
16
16
|
def deliver!
|
17
|
-
store.add_message
|
17
|
+
store.add_message(
|
18
|
+
'id' => id_generator.(),
|
19
|
+
'from_id' => from.chatbox_id,
|
20
|
+
'to_id' => to.chatbox_id,
|
21
|
+
'body' => body,
|
22
|
+
)
|
18
23
|
end
|
19
24
|
|
20
25
|
private
|
21
26
|
|
22
|
-
attr_reader :store
|
27
|
+
attr_reader :from, :to, :body, :store, :id_generator
|
23
28
|
end
|
24
29
|
end
|
data/lib/chatbox/inbox.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'chatbox/fake_missing_keywords'
|
2
|
+
require 'chatbox/message'
|
2
3
|
|
3
4
|
module Chatbox
|
4
5
|
class Inbox
|
@@ -28,7 +29,10 @@ module Chatbox
|
|
28
29
|
private
|
29
30
|
|
30
31
|
def messages
|
31
|
-
@messages ||=
|
32
|
+
@messages ||= begin
|
33
|
+
records = store.find_all_messages_by_to_id id
|
34
|
+
records.map { |record| Message.new record: record, store: store }
|
35
|
+
end
|
32
36
|
end
|
33
37
|
end
|
34
38
|
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'dalli'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Chatbox
|
5
|
+
class MemcachedStore
|
6
|
+
def initialize(namespace: nil)
|
7
|
+
@dalli = Dalli::Client.new nil, namespace: namespace
|
8
|
+
end
|
9
|
+
|
10
|
+
delegate :flush, to: :dalli
|
11
|
+
|
12
|
+
def add_message(attrs)
|
13
|
+
@dalli.set "messages/#{attrs['id']}", JSON.generate(
|
14
|
+
'from_id' => attrs['from_id'],
|
15
|
+
'to_id' => attrs['to_id'],
|
16
|
+
'body' => attrs['body'],
|
17
|
+
)
|
18
|
+
|
19
|
+
from_list = JSON.parse(@dalli.get("from/#{attrs['from_id']}") || '[]')
|
20
|
+
from_list << {'from_id' => attrs['from_id'], 'message_id' => attrs['id']}
|
21
|
+
@dalli.set "from/#{attrs['from_id']}", JSON.generate(from_list)
|
22
|
+
|
23
|
+
to_list = JSON.parse(@dalli.get("to/#{attrs['to_id']}") || '[]')
|
24
|
+
to_list << {'to_id' => attrs['to_id'], 'message_id' => attrs['id']}
|
25
|
+
@dalli.set "to/#{attrs['to_id']}", JSON.generate(to_list)
|
26
|
+
end
|
27
|
+
|
28
|
+
##########
|
29
|
+
|
30
|
+
def mark_message_read!(id)
|
31
|
+
attrs = JSON.parse @dalli.get("messages/#{id}")
|
32
|
+
attrs['read'] = true
|
33
|
+
@dalli.set "messages/#{id}", JSON.generate(attrs)
|
34
|
+
end
|
35
|
+
|
36
|
+
def mark_message_unread!(id)
|
37
|
+
attrs = JSON.parse @dalli.get("messages/#{id}")
|
38
|
+
attrs['read'] = false
|
39
|
+
@dalli.set "messages/#{id}", JSON.generate(attrs)
|
40
|
+
end
|
41
|
+
|
42
|
+
##########
|
43
|
+
|
44
|
+
def find_message(id)
|
45
|
+
if json = @dalli.get("messages/#{id}")
|
46
|
+
Record.new id, JSON.parse(json)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def find_all_messages_by_to_id(id)
|
51
|
+
if json = @dalli.get("to/#{id}")
|
52
|
+
JSON.parse(json).map do |attrs|
|
53
|
+
find_message attrs['message_id']
|
54
|
+
end
|
55
|
+
else
|
56
|
+
[]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def find_all_messages_by_from_id(id)
|
61
|
+
if json = @dalli.get("from/#{id}")
|
62
|
+
JSON.parse(json).map do |attrs|
|
63
|
+
find_message attrs['message_id']
|
64
|
+
end
|
65
|
+
else
|
66
|
+
[]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
attr_reader :dalli
|
73
|
+
|
74
|
+
class Record
|
75
|
+
def initialize(id, attrs)
|
76
|
+
@id = id
|
77
|
+
@attrs = attrs
|
78
|
+
end
|
79
|
+
|
80
|
+
attr_reader :id
|
81
|
+
|
82
|
+
%w[from_id to_id body read].each do |name|
|
83
|
+
define_method name do
|
84
|
+
attrs[name]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
attr_reader :attrs
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/lib/chatbox/memory_store.rb
CHANGED
@@ -1,21 +1,53 @@
|
|
1
1
|
module Chatbox
|
2
2
|
class MemoryStore
|
3
|
-
def add_message(
|
4
|
-
|
3
|
+
def add_message(attrs)
|
4
|
+
attrs_list << attrs
|
5
5
|
end
|
6
6
|
|
7
|
-
def
|
8
|
-
|
7
|
+
def mark_message_read!(id)
|
8
|
+
attrs_list.detect { |attrs| attrs['id'] == id }.merge! 'read' => true
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
|
11
|
+
def mark_message_unread!(id)
|
12
|
+
attrs_list.detect { |attrs| attrs['id'] == id }.merge! 'read' => false
|
13
|
+
end
|
14
|
+
|
15
|
+
##########
|
16
|
+
|
17
|
+
def find_message(id)
|
18
|
+
if attrs = attrs_list.detect { |attrs| attrs['id'] == id }
|
19
|
+
Record.new attrs
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def find_all_messages_by_to_id(id)
|
24
|
+
attrs_list.select { |attrs| attrs['to_id'] == id }.map { |attrs| Record.new attrs }
|
25
|
+
end
|
26
|
+
|
27
|
+
def find_all_messages_by_from_id(id)
|
28
|
+
attrs_list.select { |attrs| attrs['from_id'] == id }.map { |attrs| Record.new attrs }
|
13
29
|
end
|
14
30
|
|
15
31
|
private
|
16
32
|
|
17
|
-
def
|
18
|
-
@
|
33
|
+
def attrs_list
|
34
|
+
@attrs_list ||= []
|
35
|
+
end
|
36
|
+
|
37
|
+
class Record
|
38
|
+
def initialize(attrs)
|
39
|
+
@attrs = attrs
|
40
|
+
end
|
41
|
+
|
42
|
+
%w[id from_id to_id body read].each do |name|
|
43
|
+
define_method name do
|
44
|
+
attrs[name]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
attr_reader :attrs
|
19
51
|
end
|
20
52
|
end
|
21
53
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'chatbox/fake_missing_keywords'
|
2
|
+
|
3
|
+
module Chatbox
|
4
|
+
class Message
|
5
|
+
include FakeMissingKeywords
|
6
|
+
|
7
|
+
def initialize(record: req(:record), store: req(:store))
|
8
|
+
@record = record
|
9
|
+
@store = store
|
10
|
+
end
|
11
|
+
|
12
|
+
delegate :id, :from_id, :to_id, :body, to: :record
|
13
|
+
|
14
|
+
def read?
|
15
|
+
record.read
|
16
|
+
end
|
17
|
+
|
18
|
+
def mark_as_read!
|
19
|
+
store.mark_message_read! id
|
20
|
+
@record = store.find_message id
|
21
|
+
end
|
22
|
+
|
23
|
+
def mark_as_unread!
|
24
|
+
store.mark_message_unread! id
|
25
|
+
@record = store.find_message id
|
26
|
+
end
|
27
|
+
|
28
|
+
def ==(other)
|
29
|
+
other.is_a?(self.class) && record == other.record && store == other.store
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_reader :record, :store
|
35
|
+
end
|
36
|
+
end
|
data/lib/chatbox/outbox.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'chatbox/fake_missing_keywords'
|
2
|
+
require 'chatbox/message'
|
2
3
|
|
3
4
|
module Chatbox
|
4
5
|
class Outbox
|
5
6
|
include FakeMissingKeywords
|
6
7
|
|
7
|
-
def initialize(entity:
|
8
|
+
def initialize(entity: req(:entity), store: req(:store))
|
8
9
|
@id = entity.chatbox_id
|
9
10
|
@store = store
|
10
11
|
end
|
@@ -28,7 +29,10 @@ module Chatbox
|
|
28
29
|
private
|
29
30
|
|
30
31
|
def messages
|
31
|
-
@messages ||=
|
32
|
+
@messages ||= begin
|
33
|
+
records = store.find_all_messages_by_from_id(id)
|
34
|
+
records.map { |record| Message.new record: record, store: store }
|
35
|
+
end
|
32
36
|
end
|
33
37
|
end
|
34
38
|
end
|
data/lib/chatbox/version.rb
CHANGED
data/spec/chatbox_spec.rb
CHANGED
@@ -1,32 +1,8 @@
|
|
1
|
-
require 'chatbox'
|
2
|
-
|
3
1
|
describe Chatbox do
|
4
|
-
before { Chatbox.reset_config! }
|
5
|
-
|
6
|
-
context 'integration' do
|
7
|
-
it 'sending and receiving a message' do
|
8
|
-
austin = double 'entity', chatbox_id: 1
|
9
|
-
rachel = double 'entity', chatbox_id: 2
|
10
|
-
|
11
|
-
Chatbox.deliver_message! from: austin, to: rachel, body: 'Hello! How are you?'
|
12
|
-
|
13
|
-
rachels_inbox = Chatbox.fetch_inbox_for rachel
|
14
|
-
expect(rachels_inbox.size).to eq 1
|
15
|
-
message = rachels_inbox[0]
|
16
|
-
expect(message.from_id).to eq 1
|
17
|
-
expect(message.body).to eq 'Hello! How are you?'
|
18
|
-
|
19
|
-
austins_outbox = Chatbox.fetch_outbox_for austin
|
20
|
-
expect(austins_outbox.size).to eq 1
|
21
|
-
expect(message.to_id).to eq 2
|
22
|
-
expect(message.body).to eq 'Hello! How are you?'
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
2
|
describe '.deliver_message!' do
|
27
3
|
before do
|
28
|
-
@from = double 'entity'
|
29
|
-
@to = double 'entity'
|
4
|
+
@from = double 'entity', chatbox_id: 1
|
5
|
+
@to = double 'entity', chatbox_id: 2
|
30
6
|
@draft = double 'draft', deliver!: nil
|
31
7
|
allow(Chatbox::Draft).to receive(:new).and_return @draft
|
32
8
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'chatbox/memcached_store'
|
2
|
+
|
3
|
+
describe 'chatbox' do
|
4
|
+
before do
|
5
|
+
@austin = double 'entity', chatbox_id: 1
|
6
|
+
@rachel = double 'entity', chatbox_id: 2
|
7
|
+
end
|
8
|
+
|
9
|
+
[:memcached, :memory].each do |store_type|
|
10
|
+
context "using #{store_type} store" do
|
11
|
+
before do
|
12
|
+
if store_type == :memcached
|
13
|
+
memcached_store = Chatbox::MemcachedStore.new namespace: 'chatbox-text'
|
14
|
+
memcached_store.flush
|
15
|
+
Chatbox.configure { |config| config.store = memcached_store }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'sending a message' do
|
20
|
+
Chatbox.deliver_message! from: @austin, to: @rachel, body: 'Hello! How are you?'
|
21
|
+
|
22
|
+
austins_outbox = Chatbox.fetch_outbox_for @austin
|
23
|
+
expect(austins_outbox.size).to eq 1
|
24
|
+
|
25
|
+
message = austins_outbox[0]
|
26
|
+
expect(message.to_id).to eq 2
|
27
|
+
expect(message.body).to eq 'Hello! How are you?'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'receiving a message' do
|
31
|
+
Chatbox.deliver_message! from: @austin, to: @rachel, body: 'Hello! How are you?'
|
32
|
+
|
33
|
+
rachels_inbox = Chatbox.fetch_inbox_for @rachel
|
34
|
+
expect(rachels_inbox.size).to eq 1
|
35
|
+
|
36
|
+
message = rachels_inbox[0]
|
37
|
+
expect(message.from_id).to eq 1
|
38
|
+
expect(message.body).to eq 'Hello! How are you?'
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'marking messages as read' do
|
42
|
+
Chatbox.deliver_message! from: @austin, to: @rachel, body: 'Hello! How are you?'
|
43
|
+
|
44
|
+
rachels_inbox = Chatbox.fetch_inbox_for @rachel
|
45
|
+
|
46
|
+
message = rachels_inbox[0]
|
47
|
+
expect(message).to_not be_read
|
48
|
+
|
49
|
+
message.mark_as_read!
|
50
|
+
expect(message).to be_read
|
51
|
+
|
52
|
+
expect(Chatbox.fetch_inbox_for(@rachel)[0]).to be_read
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'marking messages as unread' do
|
56
|
+
Chatbox.deliver_message! from: @austin, to: @rachel, body: 'Hello! How are you?'
|
57
|
+
|
58
|
+
rachels_inbox = Chatbox.fetch_inbox_for @rachel
|
59
|
+
|
60
|
+
message = rachels_inbox[0]
|
61
|
+
expect(message).to_not be_read
|
62
|
+
|
63
|
+
message.mark_as_read!
|
64
|
+
message.mark_as_unread!
|
65
|
+
|
66
|
+
message = rachels_inbox[0]
|
67
|
+
expect(message).to_not be_read
|
68
|
+
|
69
|
+
expect(Chatbox.fetch_inbox_for(@rachel)[0]).to_not be_read
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/spec/lib/draft_spec.rb
CHANGED
@@ -9,8 +9,15 @@ describe Chatbox::Draft do
|
|
9
9
|
to: double('entity', chatbox_id: 2),
|
10
10
|
body: 'Hi',
|
11
11
|
store: store,
|
12
|
+
id_generator: -> { 'b00c7e15-668b-44b8-9336-e87e7b7d892e' },
|
13
|
+
)
|
14
|
+
|
15
|
+
expect(store).to receive(:add_message).with(
|
16
|
+
'id' => 'b00c7e15-668b-44b8-9336-e87e7b7d892e',
|
17
|
+
'from_id' => 1,
|
18
|
+
'to_id' => 2,
|
19
|
+
'body' => 'Hi',
|
12
20
|
)
|
13
|
-
expect(store).to receive(:add_message).with draft
|
14
21
|
draft.deliver!
|
15
22
|
end
|
16
23
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chatbox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Austin Schneider
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: dalli
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.7'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.7'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: activesupport
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,10 +100,13 @@ files:
|
|
86
100
|
- lib/chatbox/draft.rb
|
87
101
|
- lib/chatbox/fake_missing_keywords.rb
|
88
102
|
- lib/chatbox/inbox.rb
|
103
|
+
- lib/chatbox/memcached_store.rb
|
89
104
|
- lib/chatbox/memory_store.rb
|
105
|
+
- lib/chatbox/message.rb
|
90
106
|
- lib/chatbox/outbox.rb
|
91
107
|
- lib/chatbox/version.rb
|
92
108
|
- spec/chatbox_spec.rb
|
109
|
+
- spec/integration_spec.rb
|
93
110
|
- spec/lib/draft_spec.rb
|
94
111
|
- spec/spec_helper.rb
|
95
112
|
homepage: ''
|
@@ -118,5 +135,6 @@ specification_version: 4
|
|
118
135
|
summary: Simple messaging system.
|
119
136
|
test_files:
|
120
137
|
- spec/chatbox_spec.rb
|
138
|
+
- spec/integration_spec.rb
|
121
139
|
- spec/lib/draft_spec.rb
|
122
140
|
- spec/spec_helper.rb
|