thunderer 1.0.0 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 67917833bd7bdb8962664293c6659eabda202252
4
- data.tar.gz: 6aba43d84bda05ded6eec74460b310fbcac968d4
3
+ metadata.gz: ac9ccfa84ee7f79f531bfc0fd9fb47c75a6cb8af
4
+ data.tar.gz: a69cb3989a05b5f12cf5c5f8b0845b679702359a
5
5
  SHA512:
6
- metadata.gz: 95cd9c98d64d08426cf6ec9b7bbc3d37948a4f4417ef4d936afcca591fffdff5b63d4eaeeafb78010b2097efebcabaaec4fe131dd6c2f81fcd00a118950c2bcf
7
- data.tar.gz: 3ab00dba836fbb7dc3eead43756f15ef0fa935c7d6e613987598b07316bb52ab7bc33e3f2578c7baa0a96aadd38f17cde4a355383f3b1891c947fb77275f41d2
6
+ metadata.gz: 9ca8bb850cd751739ab961c15c2e5a60c9533a47fa9f6f33a1b6dedace7f54c8920d94c60280ab3a9a0d467745bfbb66010fd6682db1071ed550f690d9ba5e41
7
+ data.tar.gz: 241193c64ec37ffb4aeeae18ac38fa15a180b730b03e102b875c2ea9e51f9a3f3cce2cf0bd719028b61133a0619de02df169ad7b6eb80f99e4bbf06a51d85d14
data/Gemfile CHANGED
@@ -3,10 +3,15 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in thunderer.gemspec
4
4
  gemspec
5
5
 
6
+ gem 'rails', '4.2.0'
7
+ gem 'sqlite3'
8
+ gem 'jasmine'
9
+
6
10
  group :development do
7
11
  gem 'guard-rspec', require: false
8
12
  gem 'guard-jasmine'
9
13
  gem 'rsense'
14
+ gem 'sucker_punch'
10
15
  end
11
16
 
12
17
 
data/README.md CHANGED
@@ -20,10 +20,79 @@ Or install it yourself as:
20
20
 
21
21
  $ gem install thunderer
22
22
 
23
- ## Usage
23
+ ## Rails 4.2 integration
24
24
 
25
- TODO: Write usage instructions here
25
+ Now thunderer supports ActiveJob scheduling of notifications and can be configured by global setup of ActiveJob or
26
+ in thunderer.rb
26
27
 
28
+ Thunderer.configure do |config|
29
+ config.queue_adapter = :sucker_punch
30
+ config.environment = Rails.env
31
+ config.config_file_path = 'config/thunderer.yml'
32
+ end
33
+
34
+
35
+ ## Setup
36
+ Run generator:
37
+
38
+ rails g thunderer:install
39
+
40
+ It will generate thunderer.ru and thunderer.yml files. Check it and setup domain for production
41
+
42
+ Next add the JavaScript file to your application.js file manifest.
43
+
44
+ //= require thunderer
45
+
46
+ ## Usage with typical rails app
47
+
48
+ Use the `subscribe_to` helper method on any page to subscribe to a channel.
49
+
50
+ ```rhtml
51
+ <%= subscribe_to "/comments" %>
52
+ ```
53
+
54
+ Then setup active record models:
55
+
56
+ ```
57
+ class Comment < ActiveRecord::Base
58
+ include Thunderer::PublishChanges
59
+ notify_client_to_channels '/comments/new'
60
+ end
61
+ ```
62
+
63
+ ## Usage with Angular single page application
64
+
65
+ Before start using with Angular add response interceptor (ThundererInterceptor) and service ($thunderer):
66
+
67
+ //= require thunderer_angular
68
+
69
+ Inject `'Thunderer'` module to your app, and setup `$http` service
70
+
71
+ ```
72
+ ...
73
+ provider.interceptors.push('ThundererInterceptor');
74
+ ...
75
+ ```
76
+
77
+ The main deference of usage is adding special headers to json responses:
78
+
79
+ ```
80
+ class CommentsController < ApplicationController
81
+ include Thunderer::ControllerAdditions
82
+
83
+ thunderer_channels '/comments'
84
+
85
+ end
86
+ ```
87
+
88
+ After that you can subscribe in your angular controllers and directives to Faye callbacks
89
+
90
+ ```
91
+ commentAddOrChangedCallback = function(data) {
92
+ alert(data);
93
+ }
94
+ $thunderer.addListener("/comments", commentAddOrChangedCallback);
95
+ ```
27
96
  ## Contributing
28
97
 
29
98
  1. Fork it ( http://github.com/<my-github-username>/thunderer/fork )
@@ -13,6 +13,7 @@ module Thunderer
13
13
  copy_file '../../../../app/assets/javascripts/thunderer_subscription_service.js', 'public/javascripts/thunderer_subscription_service.js'
14
14
  end
15
15
  copy_file 'thunderer.ru', 'thunderer.ru'
16
+ copy_file 'thunderer.rb', 'app/config/initializers/thunderer.rb'
16
17
  end
17
18
  end
18
19
  end
@@ -0,0 +1,5 @@
1
+ Thunderer.configure do |config|
2
+ #config.queue_adapter = :sucker_punch
3
+ #config.async = true
4
+ config.config_file_path = 'config/thunderer.yml'
5
+ end
data/lib/thunderer.rb CHANGED
@@ -1,30 +1,30 @@
1
1
  require 'thunderer/version'
2
- require 'thunderer/parser'
3
- require 'thunderer/messanger'
2
+ require 'thunderer/channel_parser'
4
3
  require 'thunderer/faye_extension'
4
+ require 'thunderer/messages/async_message'
5
+ require 'thunderer/messages/base'
6
+ require 'thunderer/configuration'
5
7
  require 'digest/sha1'
6
- require 'yaml'
8
+ require 'ostruct'
7
9
  require 'thunderer/engine' if defined? Rails
8
10
 
9
11
  module Thunderer
10
- class Error < StandardError; end
12
+ class Error < StandardError;
13
+ end
11
14
 
12
15
  class << self
13
16
  attr_reader :config
14
- attr_reader :messanger
15
17
 
16
18
  def reset_config
17
- @config = {}
19
+ @config = Thunderer::Configuration.new
18
20
  end
19
21
 
20
- def load_config filename, environment
21
- reset_config
22
- config_yaml = YAML.load_file(filename)[environment]
23
- raise ArgumentError, "The #{environment} environment dose not exist" unless config_yaml
24
- config_yaml.each { |k,v| config[k.to_sym] = v }
25
- Thunderer::Messanger.configure( config[:local_server_url] || config[:server])
26
- @messanger = Thunderer::Messanger
22
+ def config
23
+ @config ||= Thunderer::Configuration.new
24
+ end
27
25
 
26
+ def configure
27
+ yield config if block_given?
28
28
  end
29
29
 
30
30
  def publish_to channel, data
@@ -32,31 +32,34 @@ module Thunderer
32
32
  end
33
33
 
34
34
  def publish_message(message)
35
- raise Error, 'No server specified, ensure thunderer.yml was loaded properly.' unless config[:server]
36
- url = URI.parse(config[:server])
37
- messanger.post(message)
35
+ raise Error, 'No server specified, ensure thunderer.yml was loaded properly.' unless config.server
36
+ if config.async
37
+ Thunderer::Messages::Base.new(message)
38
+ else
39
+ Thunderer::Messages::AsyncMessage.new(message)
40
+ end.deliver
38
41
  end
39
42
 
40
43
  def message(channel, data)
41
- {:channel => channel,
42
- :data => {
43
- :channel => channel,
44
- :data => data},
45
- :ext => {:thunderer_secret_token => config[:secret_token]}}
44
+ {channel: channel,
45
+ data: {
46
+ channel: channel,
47
+ data: data},
48
+ ext: {thunderer_secret_token: config.secret_token}}
46
49
  end
47
50
 
48
51
  def subscription(options = {})
49
- sub = {:server => config[:server], :timestamp => (Time.now.to_f * 1000).round}.merge(options)
50
- sub[:signature] = Digest::SHA1.hexdigest([config[:secret_token], sub[:channel], sub[:timestamp]].join)
52
+ sub = {server: config.server, timestamp: (Time.now.to_f * 1000).round}.merge(options)
53
+ sub[:signature] = Digest::SHA1.hexdigest([config.secret_token, sub[:channel], sub[:timestamp]].join)
51
54
  sub
52
55
  end
53
56
 
54
57
  def signature_expired?(timestamp)
55
- timestamp < ((Time.now.to_f - config[:signature_expiration])*1000).round if config[:signature_expiration]
58
+ timestamp < ((Time.now.to_f - config.signature_expiration)*1000).round if config.signature_expiration
56
59
  end
57
60
 
58
61
  def faye_app(options = {})
59
- options = {mount: '/faye', timeout: 45, extensions: [FayeExtension.new] }.merge(options)
62
+ options = {mount: '/faye', timeout: 45, extensions: [FayeExtension.new]}.merge(options)
60
63
  Faye::RackAdapter.new(options)
61
64
  end
62
65
  end
@@ -1,5 +1,5 @@
1
1
  module Thunderer
2
- module Parser
2
+ module ChannelParser
3
3
 
4
4
  class << self
5
5
  def interpolate_channel channel, object
@@ -0,0 +1,38 @@
1
+ require 'yaml'
2
+ module Thunderer
3
+ class Configuration
4
+ attr_writer :environment
5
+ attr_accessor :queue_adapter
6
+ attr_accessor :server
7
+ attr_accessor :local_server_url
8
+ attr_accessor :async
9
+ attr_accessor :secret_token
10
+ attr_accessor :signature_expiration
11
+
12
+ def initialize
13
+ @config_file_path = ''
14
+ @queue_adapter = nil
15
+ @server = nil
16
+ @secret_token = nil
17
+ @signature_expiration = 3600
18
+ @local_server_url = nil
19
+ @async = false
20
+ @environment = nil
21
+ end
22
+
23
+ def config_file_path=(value)
24
+ load_configuration(value, @environment)
25
+ end
26
+
27
+ private
28
+
29
+ def load_configuration(path, environment)
30
+ config_yaml = YAML.load_file(path)[environment]
31
+ raise ArgumentError, "The #{environment} environment dose not exist" unless config_yaml
32
+ config_yaml.each do |k, v|
33
+ self.public_send("#{k}=",v)
34
+ end
35
+ end
36
+
37
+ end
38
+ end
@@ -14,7 +14,7 @@ module Thunderer
14
14
  headers['channels'] = (self.class.channels || []).map do |channel|
15
15
  new_str = if self.class.interpolation_object && channel
16
16
  object = send(self.class.interpolation_object)
17
- Thunderer::Parser.interpolate_channel channel, object
17
+ Thunderer::ChannelParser.interpolate_channel channel, object
18
18
  else
19
19
  channel
20
20
  end
@@ -4,11 +4,6 @@ require 'thunderer/controller_additions'
4
4
  module Thunderer
5
5
  class Engine < ::Rails::Engine
6
6
 
7
- initializer 'thunderer.config' do
8
- path = Rails.root.join('config/thunderer.yml')
9
- Thunderer.load_config(path, Rails.env) if path.exist?
10
- end
11
-
12
7
  initializer :assets do |config|
13
8
  Rails.application.config.assets.paths << File.join(
14
9
  Gem.loaded_specs['faye'].full_gem_path, 'lib')
@@ -18,17 +13,5 @@ module Thunderer
18
13
  ActionView::Base.send :include, ViewHelpers
19
14
  end
20
15
 
21
- # initializer 'thunderer.controller' do
22
- # ActiveSupport.on_load(:action_controller) do
23
- # include Thunderer::ControllerAdditions
24
- # end
25
- # end
26
- #
27
- # initializer 'thunderer.active_record' do
28
- # ActiveSupport.on_load(:active_record) do
29
- # include Thunderer::PublishChanges
30
- # end
31
- # end
32
-
33
16
  end
34
17
  end
@@ -27,9 +27,9 @@ module Thunderer
27
27
 
28
28
  # Ensures the secret token is correct before publishing.
29
29
  def authenticate_publish(message)
30
- if Thunderer.config[:secret_token].nil?
30
+ if Thunderer.config.secret_token.nil?
31
31
  raise Error, 'No secret_token config set, ensure thunderer.yml is loaded properly.'
32
- elsif message['ext']['thunderer_secret_token'] != Thunderer.config[:secret_token]
32
+ elsif message['ext']['thunderer_secret_token'] != Thunderer.config.secret_token
33
33
 
34
34
  message['error'] = 'Incorrect token.'
35
35
  else
@@ -0,0 +1,32 @@
1
+ require 'active_job'
2
+ module Thunderer
3
+ module Messages
4
+ class AsyncMessage
5
+ class Job < ::ActiveJob::Base
6
+
7
+ class << self
8
+ def queue_adapter
9
+ if Thunderer.config.queue_adapter
10
+ "ActiveJob::QueueAdapters::#{Thunderer.config.queue_adapter.to_s.camelize}Adapter".constantize
11
+ else
12
+ super
13
+ end
14
+ end
15
+ end
16
+
17
+ def perform(message)
18
+ Thunderer::Messages::Base.new(message).deliver
19
+ end
20
+ end
21
+
22
+ def initialize(message)
23
+ @message = message
24
+ end
25
+
26
+ def deliver
27
+ Job.perform_later(@message)
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,40 @@
1
+ module Thunderer
2
+ module Messages
3
+ class Base
4
+
5
+ def initialize(message)
6
+ @message = message
7
+ end
8
+
9
+ def deliver
10
+ form = build_form
11
+ form.set_form_data(message: @message.to_json)
12
+ protocol.start { |h| h.request(form) }
13
+ end
14
+
15
+ private
16
+
17
+ def build_form
18
+ Net::HTTP::Post.new(uri.path.empty? ? '/' : uri.path)
19
+ end
20
+
21
+ def protocol
22
+ http = Net::HTTP.new(uri.host, uri.port)
23
+ http.use_ssl = use_ssl?
24
+ if use_ssl?
25
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
26
+ end
27
+ http
28
+ end
29
+
30
+ def uri
31
+ @uri ||= URI.parse(Thunderer.config.local_server_url || Thunderer.config.server)
32
+ end
33
+
34
+ def use_ssl?
35
+ uri.scheme == 'https'
36
+ end
37
+ end
38
+
39
+ end
40
+ end
@@ -19,7 +19,7 @@ module Thunderer
19
19
  else
20
20
  notification_message
21
21
  end
22
- Thunderer.publish_to Thunderer::Parser.interpolate_channel(channel, self), rooted_message
22
+ Thunderer.publish_to Thunderer::ChannelParser.interpolate_channel(channel, self), rooted_message
23
23
  end
24
24
  end
25
25
 
@@ -1,3 +1,3 @@
1
1
  module Thunderer
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
data/spec/spec_helper.rb CHANGED
@@ -32,12 +32,10 @@ RSpec.configure do |config|
32
32
  dep = defined?(ActiveSupport::Dependencies) ? ActiveSupport::Dependencies : ::Dependencies
33
33
  dep.autoload_paths.unshift FIXTURES_PATH
34
34
 
35
- ActiveRecord::Base.quietly do
36
- ActiveRecord::Migration.verbose = false
37
- load File.join(FIXTURES_PATH, 'schema.rb')
38
- end
35
+ ActiveRecord::Migration.verbose = false
36
+ load File.join(FIXTURES_PATH, 'schema.rb')
39
37
 
40
- ActiveRecord::Fixtures.create_fixtures(FIXTURES_PATH, ActiveRecord::Base.connection.tables)
38
+ ActiveRecord::FixtureSet.create_fixtures(FIXTURES_PATH, ActiveRecord::Base.connection.tables)
41
39
 
42
40
  config.order = 'random'
43
41
  end
@@ -19,7 +19,12 @@ describe Thunderer::ControllerAdditions do
19
19
  describe '#thunderer_channels' do
20
20
  let(:config_file_path) { 'spec/fixtures/thunderer.yml' }
21
21
  let(:environment) { 'production' }
22
- before { Thunderer.load_config(config_file_path, environment) }
22
+ before do
23
+ Thunderer.configure do |config|
24
+ config.environment = environment
25
+ config.config_file_path = config_file_path
26
+ end
27
+ end
23
28
 
24
29
  it 'should affect channels class variable' do
25
30
  controller_class.thunderer_channels('hello')
@@ -31,6 +36,7 @@ describe Thunderer::ControllerAdditions do
31
36
  expect(controller_class.interpolation_object).to include('hello')
32
37
  end
33
38
 
39
+
34
40
  it 'should setup before filter for setting headers' do
35
41
  expect(controller_class).to have_filters(:before, :add_channels_header)
36
42
  end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+ require 'thunderer/messages/async_message'
3
+ require 'rails/all'
4
+ describe Thunderer::Messages::AsyncMessage do
5
+ let(:message) { Thunderer::Messages::AsyncMessage.new }
6
+ before { Thunderer.reset_config }
7
+
8
+ describe Thunderer::Messages::AsyncMessage::Job do
9
+ let(:job) { Thunderer::Messages::AsyncMessage::Job }
10
+ describe '#queue_adapter' do
11
+ subject { job.queue_adapter }
12
+
13
+ context 'when no config' do
14
+ it { is_expected.to eq(ActiveJob::QueueAdapters::InlineAdapter) }
15
+ end
16
+
17
+ context 'when active job config set to sucker_punch' do
18
+ around do |ex|
19
+ ActiveJob::Base.queue_adapter = :sucker_punch
20
+ ex.run
21
+ ActiveJob::Base.queue_adapter = :inline
22
+ end
23
+
24
+ it { is_expected.to eq(ActiveJob::QueueAdapters::SuckerPunchAdapter) }
25
+ end
26
+
27
+ context 'but thunderer config is sucker_punch' do
28
+ before do
29
+ Thunderer.configure do |config|
30
+ config.queue_adapter = :sucker_punch
31
+ end
32
+ end
33
+
34
+ context 'and active job config is inline' do
35
+ before { ActiveJob::Base.queue_adapter = :inline }
36
+
37
+ it { is_expected.to eq(ActiveJob::QueueAdapters::SuckerPunchAdapter) }
38
+
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+
45
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Thunderer::Messages::Base do
4
+
5
+ end
@@ -1,12 +1,12 @@
1
1
  require 'spec_helper'
2
2
  require 'ostruct'
3
3
 
4
- describe Thunderer::Parser do
4
+ describe Thunderer::ChannelParser do
5
5
 
6
6
  let(:object) { OpenStruct.new(first: 1, second: 2) }
7
7
 
8
8
  describe '#interpolate_channel' do
9
- subject { Thunderer::Parser.interpolate_channel(channel, object) }
9
+ subject { Thunderer::ChannelParser.interpolate_channel(channel, object) }
10
10
 
11
11
  context 'when channel have no interpolation' do
12
12
  let(:channel) { 'without interpolation string' }
@@ -4,13 +4,18 @@ describe Thunderer do
4
4
  before { Thunderer.reset_config }
5
5
  let(:config_file_path) { 'spec/fixtures/thunderer.yml' }
6
6
  let(:environment) { 'production' }
7
- let(:load_config) { Thunderer.load_config(config_file_path, environment) }
7
+ let(:load_config) do
8
+ Thunderer.configure do |config|
9
+ config.environment = environment
10
+ config.config_file_path = config_file_path
11
+ end
12
+ end
8
13
 
9
14
  describe 'default state' do
10
15
  describe '#config' do
11
16
  subject { Thunderer.config }
12
17
 
13
- it { is_expected.to eq({}) }
18
+ it { is_expected.to be_a(Thunderer::Configuration)}
14
19
 
15
20
  end
16
21
  end
@@ -22,11 +27,19 @@ describe Thunderer do
22
27
  context 'when config environment was exists' do
23
28
  before { load_config }
24
29
 
25
- it { is_expected.to include(:server => 'http://example.com/faye') }
30
+ {
31
+ server: 'http://example.com/faye',
32
+ secret_token: 'PRODUCTION_SECRET_TOKEN',
33
+ signature_expiration: 600
34
+ }.each do |method, value|
35
+ context "#config.#{method}" do
36
+ subject { Thunderer.config.send(method)}
26
37
 
27
- it { is_expected.to include(:secret_token => 'PRODUCTION_SECRET_TOKEN') }
38
+ it { is_expected.to eq(value) }
39
+
40
+ end
41
+ end
28
42
 
29
- it { is_expected.to include(:signature_expiration => 600) }
30
43
  end
31
44
 
32
45
  context 'when config environment was not exists' do
@@ -40,30 +53,13 @@ describe Thunderer do
40
53
 
41
54
  end
42
55
 
43
- describe 'Thunderer::Messanger configuration' do
44
- subject { Thunderer::Messanger.config }
45
-
46
- it { is_expected.not_to eq({}) }
47
-
48
- context 'when config have local_server_url' do
49
- let(:config_file_path) { 'spec/fixtures/thunderer_local_server.yml' }
50
- let(:environment) { 'production' }
51
-
52
- before { load_config }
53
-
54
- it { is_expected.to include('uri'=>URI.parse('http://localhost:3000')) }
55
-
56
- end
57
-
58
- end
59
-
60
56
  end
61
57
 
62
58
  describe '#subscription' do
63
59
  before { load_config }
64
60
  let!(:time_mock) { Time.now }
65
61
  before { allow(Time).to receive(:now) { time_mock } }
66
- before { Thunderer.config[:server] = 'server' }
62
+ before { Thunderer.config.server = 'server' }
67
63
  subject { Thunderer.subscription }
68
64
 
69
65
  it { is_expected.to include(:timestamp => (time_mock.to_f * 1000).round) }
@@ -77,7 +73,7 @@ describe Thunderer do
77
73
  end
78
74
 
79
75
  describe 'signature' do
80
- before { Thunderer.config[:secret_token] = 'token' }
76
+ before { Thunderer.config.secret_token = 'token' }
81
77
  subject { Thunderer.subscription(:timestamp => 123, :channel => 'channel') }
82
78
 
83
79
  it { is_expected.to include(:signature => Digest::SHA1.hexdigest('tokenchannel123')) }
@@ -91,7 +87,7 @@ describe Thunderer do
91
87
 
92
88
  describe 'formatting' do
93
89
  let(:secret_token) { 'token' }
94
- before { Thunderer.config[:secret_token] = secret_token }
90
+ before { Thunderer.config.secret_token = secret_token }
95
91
 
96
92
  subject { Thunderer.message('chan', :foo => 'bar') }
97
93
 
@@ -116,7 +112,7 @@ describe Thunderer do
116
112
  before { load_config }
117
113
 
118
114
  specify do
119
- expect(Thunderer::Messanger).to receive(:post)
115
+ expect_any_instance_of(Thunderer::Messages::Base).to receive(:deliver)
120
116
  subject
121
117
  end
122
118
  end
@@ -154,7 +150,7 @@ describe Thunderer do
154
150
 
155
151
  describe 'signature_expired?' do
156
152
  let(:expiration) { 30*60 }
157
- before { Thunderer.config[:signature_expiration] = expiration }
153
+ before { Thunderer.config.signature_expiration = expiration }
158
154
  subject { Thunderer.signature_expired?(time) }
159
155
 
160
156
  context 'when time greater than expiration ' do
data/thunderer.gemspec CHANGED
@@ -15,11 +15,7 @@ Gem::Specification.new do |spec|
15
15
 
16
16
  spec.add_dependency 'faye'
17
17
 
18
- spec.add_runtime_dependency 'activesupport'
19
- spec.add_development_dependency 'rails'
20
- spec.add_development_dependency 'rspec'
21
- spec.add_development_dependency 'jasmine'
22
- spec.add_development_dependency 'sqlite3'
18
+ spec.add_runtime_dependency 'activesupport', '4.2.0'
23
19
 
24
20
  spec.files = `git ls-files -z`.split("\x0")
25
21
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thunderer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Chubarov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-22 00:00:00.000000000 Z
11
+ date: 2014-12-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faye
@@ -28,72 +28,16 @@ dependencies:
28
28
  name: activesupport
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 4.2.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: rails
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: rspec
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: jasmine
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
38
+ - - '='
81
39
  - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: sqlite3
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
40
+ version: 4.2.0
97
41
  - !ruby/object:Gem::Dependency
98
42
  name: bundler
99
43
  requirement: !ruby/object:Gem::Requirement
@@ -140,14 +84,17 @@ files:
140
84
  - app/assets/javascripts/thunderer.js
141
85
  - app/assets/javascripts/thunderer_angular.js
142
86
  - lib/generators/thunderer/install_generator.rb
87
+ - lib/generators/thunderer/templates/thunderer.rb
143
88
  - lib/generators/thunderer/templates/thunderer.ru
144
89
  - lib/generators/thunderer/templates/thunderer.yml
145
90
  - lib/thunderer.rb
91
+ - lib/thunderer/channel_parser.rb
92
+ - lib/thunderer/configuration.rb
146
93
  - lib/thunderer/controller_additions.rb
147
94
  - lib/thunderer/engine.rb
148
95
  - lib/thunderer/faye_extension.rb
149
- - lib/thunderer/messanger.rb
150
- - lib/thunderer/parser.rb
96
+ - lib/thunderer/messages/async_message.rb
97
+ - lib/thunderer/messages/base.rb
151
98
  - lib/thunderer/publish_changes.rb
152
99
  - lib/thunderer/version.rb
153
100
  - lib/thunderer/view_helpers.rb
@@ -166,7 +113,8 @@ files:
166
113
  - spec/support/controller_macros.rb
167
114
  - spec/support/matchers/have_filter.rb
168
115
  - spec/thunderer/controller_aditions_spec.rb
169
- - spec/thunderer/messanger_spec.rb
116
+ - spec/thunderer/messages/async_message_spec.rb
117
+ - spec/thunderer/messages/base_spec.rb
170
118
  - spec/thunderer/parser_spec.rb
171
119
  - spec/thunderer/publish_changes_spec.rb
172
120
  - spec/thunderer_spec.rb
@@ -211,7 +159,8 @@ test_files:
211
159
  - spec/support/controller_macros.rb
212
160
  - spec/support/matchers/have_filter.rb
213
161
  - spec/thunderer/controller_aditions_spec.rb
214
- - spec/thunderer/messanger_spec.rb
162
+ - spec/thunderer/messages/async_message_spec.rb
163
+ - spec/thunderer/messages/base_spec.rb
215
164
  - spec/thunderer/parser_spec.rb
216
165
  - spec/thunderer/publish_changes_spec.rb
217
166
  - spec/thunderer_spec.rb
@@ -1,50 +0,0 @@
1
- module Thunderer
2
- module Messanger
3
- class ConfigurationError < StandardError; end
4
-
5
- class << self
6
- attr_reader :config
7
-
8
- def reset_config
9
- @config = {}
10
- end
11
-
12
- def configure url
13
- reset_config
14
- uri = URI.parse(url)
15
- @config['uri'] = uri
16
- @config['use_ssl'] = uri.scheme == 'https'
17
- end
18
-
19
- def post( message )
20
- raise ConfigurationError if not_configured?
21
-
22
- form = build_form
23
- form.set_form_data(:message => message.to_json)
24
- protocol.start { |h| h.request(form) }
25
- end
26
-
27
- private
28
-
29
- def build_form
30
- uri = @config['uri']
31
- Net::HTTP::Post.new(uri.path.empty? ? '/' : uri.path)
32
- end
33
-
34
- def protocol
35
- uri = @config['uri']
36
- http = Net::HTTP.new(uri.host, uri.port)
37
- http.use_ssl = @config['use_ssl']
38
- if @config['use_ssl']
39
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
40
- end
41
- http
42
- end
43
-
44
- def not_configured?
45
- @config == {}
46
- end
47
-
48
- end
49
- end
50
- end
@@ -1,70 +0,0 @@
1
- require 'spec_helper'
2
- require 'thunderer/messanger'
3
-
4
- describe Thunderer::Messanger do
5
- let(:messanger) { Thunderer::Messanger }
6
- before { Thunderer::Messanger.reset_config }
7
-
8
- it 'default have nil uri' do
9
- expect(messanger.config['uri']).to eq(nil)
10
- end
11
-
12
- it 'default have nil use_ssl' do
13
- expect(messanger.config['use_ssl']).to eq(nil)
14
- end
15
-
16
- describe '#post' do
17
- subject { messanger.post(message) }
18
-
19
- context 'with default config' do
20
- let(:message) { double(:message) }
21
-
22
- specify do
23
- expect { subject }.to raise_error Thunderer::Messanger::ConfigurationError
24
- end
25
-
26
- end
27
-
28
- context 'with correct config' do
29
- before { Thunderer::Messanger.configure('http://localhost:3000') }
30
- let(:http_form) { double(:form) }
31
- let(:http) { double(:http) }
32
- let(:message) { 'Hello world' }
33
- before { allow(Net::HTTP::Post).to receive(:new).with('/').and_return(http_form) }
34
- before { allow(Net::HTTP).to receive(:new).with('localhost', 3000).and_return(http) }
35
- before { allow(http).to receive(:use_ssl=) }
36
-
37
-
38
- specify do
39
- expect(http_form).to receive(:set_form_data).with(message: message.to_json)
40
- expect(http).to receive(:start).and_yield(http)
41
- expect(http).to receive(:request).with(http_form).and_return(:result)
42
- expect(subject).to eq(:result)
43
- end
44
-
45
- end
46
-
47
-
48
- end
49
-
50
-
51
- describe '#configure' do
52
-
53
- it 'parse url and set configuration' do
54
- messanger.configure('http://google.ru')
55
- expect(messanger.config).not_to eq({})
56
- end
57
-
58
- it 'set use_ssl to false for http' do
59
- messanger.configure('http://google.ru')
60
- expect(messanger.config['use_ssl']).to eq(false)
61
- end
62
-
63
- it 'set use_ssl to false for https' do
64
- messanger.configure('https://google.ru')
65
- expect(messanger.config['use_ssl']).to eq(true)
66
- end
67
-
68
- end
69
-
70
- end