thunderer 0.9.1 → 1.0.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: f06c6d86a7fb9ab91ccc695100d1bb38522a09e1
4
- data.tar.gz: ed2ecd2a1364b28d2fa8a7352fc108766c2020e1
3
+ metadata.gz: 67917833bd7bdb8962664293c6659eabda202252
4
+ data.tar.gz: 6aba43d84bda05ded6eec74460b310fbcac968d4
5
5
  SHA512:
6
- metadata.gz: a0eedfda8684dd26ce682ab4746c48c8dfdf5238b1d841dfb1ef933d3c82112bb851285c5b57200c9d33ee678c230ff12094eb53622da9ca80abf27976090317
7
- data.tar.gz: 41b061f20bce2aad21520d7661a8fd8ff3a64d44781a84c80515cd36bf981d213596143a8661547091c5a4895e0c734379691a34ab2f7dbd2a33704e4a0ee07f
6
+ metadata.gz: 95cd9c98d64d08426cf6ec9b7bbc3d37948a4f4417ef4d936afcca591fffdff5b63d4eaeeafb78010b2097efebcabaaec4fe131dd6c2f81fcd00a118950c2bcf
7
+ data.tar.gz: 3ab00dba836fbb7dc3eead43756f15ef0fa935c7d6e613987598b07316bb52ab7bc33e3f2578c7baa0a96aadd38f17cde4a355383f3b1891c947fb77275f41d2
data/.travis.yml CHANGED
@@ -3,7 +3,7 @@ rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
5
  - 2.1.0
6
+ - 2.1.2
6
7
  addons:
7
8
  code_climate:
8
- repo_token:
9
- secure: kQfmRpllfvpVjss75SRQKDJ70j72doORRsr8EQyY3cJsoAnwfu8E25/JZ+ZoG25AS+Z6dNYpSH0unrsqzbaSGucFfnQD0TiGINJhs36svHhtrP+JDSxwE38PyKu3tX07TMDxfZ0ig8OfuEuB3RB+E/1/1fy4RrrDn+ZIQN0dIHs=
9
+ repo_token: c277309738ed74f1285b9724c26528315c67b45850f09892970bad596fc15882
data/Gemfile CHANGED
@@ -13,4 +13,5 @@ end
13
13
  group :test do
14
14
  gem 'rspec'
15
15
  gem 'codeclimate-test-reporter', require: nil
16
+ gem 'timecop'
16
17
  end
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  [![Build Status](https://travis-ci.org/chubarovNick/thunderer.svg?branch=master)](https://travis-ci.org/chubarovNick/thunderer)
2
- [![Code Climate](https://codeclimate.com/github/chubarovNick/thunderer.png)](https://codeclimate.com/github/chubarovNick/thunderer)
2
+ [![Code Climate](https://codeclimate.com/github/chubarovNick/thunderer/badges/gpa.svg)](https://codeclimate.com/github/chubarovNick/thunderer)
3
3
  [![Dependency Status](https://gemnasium.com/chubarovNick/thunderer.svg)](https://gemnasium.com/chubarovNick/thunderer)
4
+ [![Test Coverage](https://codeclimate.com/github/chubarovNick/thunderer/badges/coverage.svg)](https://codeclimate.com/github/chubarovNick/thunderer)
4
5
  # Thunderer
5
6
 
6
7
  Thunderer is gem for publishing messages through [Faye](http://faye.jcoglan.com/). It allows you to easily provide real-time updates through an open socket without tying
data/Rakefile CHANGED
@@ -7,6 +7,6 @@ RSpec::Core::RakeTask.new do |t|
7
7
  t.verbose = false
8
8
  end
9
9
 
10
- task default: :spec
10
+ task default: [:spec, "jasmine:ci"]
11
11
  require 'jasmine'
12
12
  load 'jasmine/tasks/jasmine.rake'
@@ -4,8 +4,8 @@ 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")
7
+ initializer 'thunderer.config' do
8
+ path = Rails.root.join('config/thunderer.yml')
9
9
  Thunderer.load_config(path, Rails.env) if path.exist?
10
10
  end
11
11
 
@@ -14,7 +14,7 @@ module Thunderer
14
14
  Gem.loaded_specs['faye'].full_gem_path, 'lib')
15
15
  end
16
16
 
17
- initializer "thunderer.view_helpers" do
17
+ initializer 'thunderer.view_helpers' do
18
18
  ActionView::Base.send :include, ViewHelpers
19
19
  end
20
20
 
@@ -5,9 +5,9 @@ module Thunderer
5
5
  # Callback to handle incoming Faye messages. This authenticates both
6
6
  # subscribe and publish calls.
7
7
  def incoming(message, callback)
8
- if message["channel"] == "/meta/subscribe"
8
+ if message['channel'] == '/meta/subscribe'
9
9
  authenticate_subscribe(message)
10
- elsif message["channel"] !~ %r{^/meta/}
10
+ elsif message['channel'] !~ %r{^/meta/}
11
11
  authenticate_publish(message)
12
12
  end
13
13
  callback.call(message)
@@ -17,23 +17,23 @@ module Thunderer
17
17
 
18
18
  # Ensure the subscription signature is correct and that it has not expired.
19
19
  def authenticate_subscribe(message)
20
- subscription = Thunderer.subscription(:channel => message["subscription"], :timestamp => message["ext"]["thunderer_timestamp"])
21
- if message["ext"]["thunderer_signature"] != subscription[:signature]
22
- message["error"] = "Incorrect signature."
23
- elsif Thunderer.signature_expired? message["ext"]["thunderer_timestamp"].to_i
24
- message["error"] = "Signature has expired."
20
+ subscription = Thunderer.subscription(:channel => message['subscription'], :timestamp => message['ext']['thunderer_timestamp'])
21
+ if message['ext']['thunderer_signature'] != subscription[:signature]
22
+ message['error'] = 'Incorrect signature.'
23
+ elsif Thunderer.signature_expired? message['ext']['thunderer_timestamp'].to_i
24
+ message['error'] = 'Signature has expired.'
25
25
  end
26
26
  end
27
27
 
28
28
  # Ensures the secret token is correct before publishing.
29
29
  def authenticate_publish(message)
30
30
  if Thunderer.config[:secret_token].nil?
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]
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]
33
33
 
34
- message["error"] = "Incorrect token."
34
+ message['error'] = 'Incorrect token.'
35
35
  else
36
- message["ext"]["thunderer_secret_token"] = nil
36
+ message['ext']['thunderer_secret_token'] = nil
37
37
  end
38
38
  end
39
39
  end
@@ -16,12 +16,12 @@ module Thunderer
16
16
  @config['use_ssl'] = uri.scheme == 'https'
17
17
  end
18
18
 
19
- def post message
19
+ def post( message )
20
20
  raise ConfigurationError if not_configured?
21
21
 
22
22
  form = build_form
23
23
  form.set_form_data(:message => message.to_json)
24
- protocol.start {|h| h.request(form)}
24
+ protocol.start { |h| h.request(form) }
25
25
  end
26
26
 
27
27
  private
@@ -1,3 +1,3 @@
1
1
  module Thunderer
2
- VERSION = '0.9.1'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -14,7 +14,7 @@ module Thunderer
14
14
  # options.
15
15
  def subscribe_to(channel)
16
16
  subscription = Thunderer.subscription(:channel => channel)
17
- content_tag "script", :type => "text/javascript" do
17
+ content_tag 'script', :type => 'text/javascript' do
18
18
  raw("Thunderer.sign(#{subscription.to_json});")
19
19
  end
20
20
  end
data/lib/thunderer.rb CHANGED
@@ -1,10 +1,10 @@
1
- require "thunderer/version"
1
+ require 'thunderer/version'
2
2
  require 'thunderer/parser'
3
3
  require 'thunderer/messanger'
4
4
  require 'thunderer/faye_extension'
5
- require "digest/sha1"
5
+ require 'digest/sha1'
6
6
  require 'yaml'
7
- require "thunderer/engine" if defined? Rails
7
+ require 'thunderer/engine' if defined? Rails
8
8
 
9
9
  module Thunderer
10
10
  class Error < StandardError; end
@@ -22,7 +22,7 @@ module Thunderer
22
22
  config_yaml = YAML.load_file(filename)[environment]
23
23
  raise ArgumentError, "The #{environment} environment dose not exist" unless config_yaml
24
24
  config_yaml.each { |k,v| config[k.to_sym] = v }
25
- Thunderer::Messanger.configure(config[:server])
25
+ Thunderer::Messanger.configure( config[:local_server_url] || config[:server])
26
26
  @messanger = Thunderer::Messanger
27
27
 
28
28
  end
@@ -32,7 +32,7 @@ module Thunderer
32
32
  end
33
33
 
34
34
  def publish_message(message)
35
- raise Error, "No server specified, ensure private_pub.yml was loaded properly." unless config[:server]
35
+ raise Error, 'No server specified, ensure thunderer.yml was loaded properly.' unless config[:server]
36
36
  url = URI.parse(config[:server])
37
37
  messanger.post(message)
38
38
  end
@@ -0,0 +1,6 @@
1
+ dummy:
2
+ name : Joe
3
+ id : 1
4
+ created_at: 1999-02-19 08:00
5
+ updated_at: 1999-02-19 08:00
6
+
@@ -0,0 +1,9 @@
1
+ ActiveRecord::Schema.define do
2
+
3
+ create_table "dummy_classes", :force => true do |t|
4
+ t.string "name"
5
+ t.datetime "created_at", :null => false
6
+ t.datetime "updated_at", :null => false
7
+ end
8
+
9
+ end
@@ -0,0 +1,10 @@
1
+ development:
2
+ server: http://dev.local:9292/faye
3
+ secret_token: DEVELOPMENT_SECRET_TOKEN
4
+ signature_expiration: 600
5
+ production:
6
+ server: http://example.com/faye
7
+ local_server_url: http://localhost:3000
8
+ secret_token: PRODUCTION_SECRET_TOKEN
9
+ signature_expiration: 600
10
+
@@ -1,7 +1,16 @@
1
1
  describe('Thunderer', function () {
2
2
  var doc;
3
3
  beforeEach(function () {
4
- Faye = {};
4
+ Faye = {
5
+ Client: function () {
6
+ return {
7
+ addExtension: function () {
8
+ }
9
+ }
10
+
11
+ }
12
+
13
+ };
5
14
  doc = {};
6
15
  });
7
16
 
@@ -110,8 +119,11 @@ describe('Thunderer', function () {
110
119
  });
111
120
 
112
121
  it("adds fayeCallback when client and server aren't available", function() {
113
- Thunderer.faye("callback");
114
- expect(Thunderer.fayeCallbacks[0]).toEqual("callback");
122
+ Thunderer.faye(function () {
123
+ return 'callback';
124
+ });
125
+ expect(Thunderer.fayeCallbacks[0]).toEqual(jasmine.any(Function));
126
+ expect(Thunderer.fayeCallbacks[0]()).toEqual('callback')
115
127
  });
116
128
 
117
129
 
data/spec/spec_helper.rb CHANGED
@@ -10,20 +10,34 @@ require 'bundler/setup'
10
10
  require 'support/matchers/have_filter'
11
11
  require 'json'
12
12
  require 'faye'
13
+ require 'active_record'
13
14
  require 'support/controller_macros'
15
+ require 'active_record/fixtures'
14
16
  Bundler.setup
15
17
 
16
18
  require 'thunderer'
17
19
  RSpec.configure do |config|
18
- config.treat_symbols_as_metadata_keys_with_true_values = true
20
+ FIXTURES_PATH = File.join(File.dirname(__FILE__), 'fixtures')
21
+
22
+
23
+ ActiveRecord::Base.establish_connection(
24
+ adapter: 'sqlite3',
25
+ database: ':memory:'
26
+ )
19
27
  config.run_all_when_everything_filtered = true
20
28
  config.filter_run :focus
21
-
29
+ config.raise_errors_for_deprecations!
22
30
  config.include ControllerMacros
23
31
 
24
- # Run specs in random order to surface order dependencies. If you find an
25
- # order dependency and want to debug it, you can fix the order by providing
26
- # the seed, which is printed after each run.
27
- # --seed 1234
32
+ dep = defined?(ActiveSupport::Dependencies) ? ActiveSupport::Dependencies : ::Dependencies
33
+ dep.autoload_paths.unshift FIXTURES_PATH
34
+
35
+ ActiveRecord::Base.quietly do
36
+ ActiveRecord::Migration.verbose = false
37
+ load File.join(FIXTURES_PATH, 'schema.rb')
38
+ end
39
+
40
+ ActiveRecord::Fixtures.create_fixtures(FIXTURES_PATH, ActiveRecord::Base.connection.tables)
41
+
28
42
  config.order = 'random'
29
43
  end
@@ -17,32 +17,35 @@ describe Thunderer::ControllerAdditions do
17
17
  let(:controller_class) { MyController }
18
18
 
19
19
  describe '#thunderer_channels' do
20
+ let(:config_file_path) { 'spec/fixtures/thunderer.yml' }
21
+ let(:environment) { 'production' }
22
+ before { Thunderer.load_config(config_file_path, environment) }
20
23
 
21
- it 'should affect channels class variable' do
22
- controller_class.thunderer_channels('hello')
23
- expect(controller_class.channels).to include('hello')
24
- end
25
-
26
- it 'should affect interpolation_object of class' do
27
- controller_class.thunderer_channels(object: 'hello')
28
- expect(controller_class.interpolation_object).to include('hello')
29
- end
24
+ it 'should affect channels class variable' do
25
+ controller_class.thunderer_channels('hello')
26
+ expect(controller_class.channels).to include('hello')
27
+ end
30
28
 
31
- it 'should setup before filter for setting headers' do
32
- expect(controller_class).to have_filters(:before, :add_channels_header)
33
- end
29
+ it 'should affect interpolation_object of class' do
30
+ controller_class.thunderer_channels(object: 'hello')
31
+ expect(controller_class.interpolation_object).to include('hello')
32
+ end
34
33
 
35
- context 'for instance of controller' do
36
- subject(:controller) { controller_class.new }
34
+ it 'should setup before filter for setting headers' do
35
+ expect(controller_class).to have_filters(:before, :add_channels_header)
36
+ end
37
37
 
38
- # it 'should add special header for index response' do
39
- # controller_class.thunderer_channels('hello')
40
- # allow(controller).to receive(:headers)
41
- # controller.send(:add_channels_header)
42
- # end
38
+ context 'for instance of controller' do
39
+ subject(:controller) { controller_class.new }
43
40
 
41
+ it 'should add special header for index response' do
42
+ controller_class.thunderer_channels('hello')
43
+ allow(controller).to receive(:headers) { {} }
44
+ controller.send(:add_channels_header)
44
45
  end
45
46
 
47
+ end
48
+
46
49
  end
47
50
 
48
51
  end
@@ -13,17 +13,41 @@ describe Thunderer::Messanger do
13
13
  expect(messanger.config['use_ssl']).to eq(nil)
14
14
  end
15
15
 
16
- context 'with default config' do
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
17
25
 
18
- it 'should raise error when you try post message' do
19
- message = double(:message)
20
- expect {
21
- messanger.post(message)
22
- }.to raise_error Thunderer::Messanger::ConfigurationError
23
26
  end
24
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
+
25
48
  end
26
49
 
50
+
27
51
  describe '#configure' do
28
52
 
29
53
  it 'parse url and set configuration' do
@@ -11,22 +11,22 @@ describe Thunderer::Parser do
11
11
  context 'when channel have no interpolation' do
12
12
  let(:channel) { 'without interpolation string' }
13
13
 
14
- it { should == channel }
14
+ it { is_expected.to eq(channel) }
15
15
  end
16
16
 
17
17
  context 'when channel have one interpolation sequence' do
18
18
  let(:channel) { '/hello/:first' }
19
19
 
20
- it { should include('1') }
20
+ it { is_expected.to include('1') }
21
21
 
22
22
  end
23
23
 
24
24
  context 'when channel have two interpolations' do
25
25
  let(:channel) { '/hello/:first/world/:second' }
26
26
 
27
- it { should include('1') }
27
+ it { is_expected.to include('1') }
28
28
 
29
- it { should include('2') }
29
+ it { is_expected.to include('2') }
30
30
  end
31
31
 
32
32
 
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+ require 'thunderer/publish_changes'
3
+
4
+ class DummyClass < ActiveRecord::Base
5
+ include Thunderer::PublishChanges
6
+ end
7
+
8
+ describe Thunderer::PublishChanges do
9
+ let(:dummy_class) { DummyClass }
10
+ let(:dummy) { DummyClass.new }
11
+
12
+ context 'when notify_client_to_channels with only channel' do
13
+ before do
14
+ dummy_class.notify_client_to_channels('/channel')
15
+ end
16
+
17
+ context 'channels' do
18
+ subject { dummy_class.channels }
19
+
20
+ it { is_expected.to eq(['/channel']) }
21
+
22
+ end
23
+
24
+ context 'callback' do
25
+ before { expect(Thunderer).to receive(:publish_to).with('/channel', dummy) }
26
+ subject { dummy.save }
27
+
28
+ it { is_expected.to eq(true) }
29
+
30
+ end
31
+
32
+ end
33
+
34
+ context 'when notify_client_to_channels message_root' do
35
+ before do
36
+ dummy_class.notify_client_to_channels('/channel', message_root: 'root')
37
+ end
38
+
39
+ context 'channels' do
40
+ subject { dummy_class.channels }
41
+
42
+ it { is_expected.to eq(['/channel']) }
43
+
44
+ end
45
+
46
+ context 'callback' do
47
+ before { expect(Thunderer).to receive(:publish_to).with('/channel', Hash['root', dummy]) }
48
+ subject { dummy.save }
49
+
50
+ it { is_expected.to eq(true) }
51
+
52
+ end
53
+ end
54
+
55
+ context 'when notify_client_to_channels block' do
56
+ let(:dummy) { DummyClass.find(1)}
57
+ before do
58
+ dummy_class.notify_client_to_channels '/channel' do |object|
59
+ {id: object.id}
60
+ end
61
+ end
62
+
63
+ context 'channels' do
64
+ subject { dummy_class.channels }
65
+
66
+ it { is_expected.to eq(['/channel']) }
67
+
68
+ end
69
+
70
+ context 'callback' do
71
+ before { expect(Thunderer).to receive(:publish_to).with('/channel', {id: dummy.id}) }
72
+ subject { dummy.save }
73
+
74
+ it { is_expected.to eq(true) }
75
+
76
+ end
77
+ end
78
+
79
+ end
@@ -2,107 +2,183 @@ require 'spec_helper'
2
2
 
3
3
  describe Thunderer do
4
4
  before { Thunderer.reset_config }
5
+ let(:config_file_path) { 'spec/fixtures/thunderer.yml' }
6
+ let(:environment) { 'production' }
7
+ let(:load_config) { Thunderer.load_config(config_file_path, environment) }
5
8
 
6
- it "defaults server to nil" do
7
- Thunderer.config[:server].should be_nil
8
- end
9
+ describe 'default state' do
10
+ describe '#config' do
11
+ subject { Thunderer.config }
9
12
 
10
- it "defaults signature_expiration to nil" do
11
- Thunderer.config[:signature_expiration].should be_nil
12
- end
13
+ it { is_expected.to eq({}) }
13
14
 
14
- it "defaults subscription timestamp to current time in milliseconds" do
15
- time = Time.now
16
- Time.stub(:now).and_return(time)
17
- Thunderer.subscription[:timestamp].should eq((time.to_f * 1000).round)
15
+ end
18
16
  end
19
17
 
20
- it "loads a simple configuration file via load_config" do
21
- Thunderer.load_config("spec/fixtures/thunderer.yml", "production")
22
- Thunderer.config[:server].should eq("http://example.com/faye")
23
- Thunderer.config[:secret_token].should eq("PRODUCTION_SECRET_TOKEN")
24
- Thunderer.config[:signature_expiration].should eq(600)
25
- end
18
+ describe '#load_config' do
26
19
 
27
- it 'also configure Thunderer::Messanger when load config' do
28
- Thunderer.load_config("spec/fixtures/thunderer.yml", "production")
29
- # expect(Thunderer.messanger).to be_kind_of(Thunderer::Messanger)
30
- expect(Thunderer.messanger.config).not_to be_nil
31
- end
20
+ subject { Thunderer.config }
32
21
 
33
- it "raises an exception if an invalid environment is passed to load_config" do
34
- expect {
35
- Thunderer.load_config("spec/fixtures/thunderer.yml", :test)
36
- }.to raise_error ArgumentError
37
- end
22
+ context 'when config environment was exists' do
23
+ before { load_config }
38
24
 
25
+ it { is_expected.to include(:server => 'http://example.com/faye') }
39
26
 
40
- it "includes channel, server, and custom time in subscription" do
41
- Thunderer.config[:server] = "server"
42
- subscription = Thunderer.subscription(:timestamp => 123, :channel => "hello")
43
- subscription[:timestamp].should eq(123)
44
- subscription[:channel].should eq("hello")
45
- subscription[:server].should eq("server")
46
- end
27
+ it { is_expected.to include(:secret_token => 'PRODUCTION_SECRET_TOKEN') }
47
28
 
48
- it "does a sha1 digest of channel, timestamp, and secret token" do
49
- Thunderer.config[:secret_token] = "token"
50
- subscription = Thunderer.subscription(:timestamp => 123, :channel => "channel")
51
- subscription[:signature].should eq(Digest::SHA1.hexdigest("tokenchannel123"))
52
- end
29
+ it { is_expected.to include(:signature_expiration => 600) }
30
+ end
53
31
 
54
- it "formats a message hash given a channel and a hash" do
55
- Thunderer.config[:secret_token] = "token"
56
- Thunderer.message("chan", :foo => "bar").should eq(
57
- :ext => {:thunderer_secret_token => "token"},
58
- :channel => "chan",
59
- :data => {
60
- :channel => "chan",
61
- :data => {:foo => "bar"}
62
- }
63
- )
64
- end
32
+ context 'when config environment was not exists' do
33
+ let(:environment) { 'test' }
34
+
35
+ specify do
36
+ expect {
37
+ load_config
38
+ }.to raise_error ArgumentError
39
+ end
40
+
41
+ end
42
+
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' }
65
51
 
66
- it "publish message as json to server using Net::HTTP" do
67
- message = 'foo'
68
- Thunderer.load_config("spec/fixtures/thunderer.yml", "production")
52
+ before { load_config }
53
+
54
+ it { is_expected.to include('uri'=>URI.parse('http://localhost:3000')) }
55
+
56
+ end
57
+
58
+ end
69
59
 
70
- expect(Thunderer::Messanger).to receive(:post)
71
- Thunderer.publish_message(message)
72
60
  end
73
61
 
74
-
75
- it "raises an exception if no server is specified when calling publish_message" do
76
- lambda {
77
- Thunderer.publish_message("foo")
78
- }.should raise_error(Thunderer::Error)
62
+ describe '#subscription' do
63
+ before { load_config }
64
+ let!(:time_mock) { Time.now }
65
+ before { allow(Time).to receive(:now) { time_mock } }
66
+ before { Thunderer.config[:server] = 'server' }
67
+ subject { Thunderer.subscription }
68
+
69
+ it { is_expected.to include(:timestamp => (time_mock.to_f * 1000).round) }
70
+
71
+ context 'when #subscription pass params' do
72
+ subject { Thunderer.subscription(:timestamp => 123, :channel => 'hello') }
73
+
74
+ it { is_expected.to include(:timestamp => 123) }
75
+ it { is_expected.to include(:channel => 'hello') }
76
+ it { is_expected.to include(:server => 'server') }
77
+ end
78
+
79
+ describe 'signature' do
80
+ before { Thunderer.config[:secret_token] = 'token' }
81
+ subject { Thunderer.subscription(:timestamp => 123, :channel => 'channel') }
82
+
83
+ it { is_expected.to include(:signature => Digest::SHA1.hexdigest('tokenchannel123')) }
84
+
85
+ end
86
+
87
+
79
88
  end
80
89
 
81
- it "publish_to passes message to publish_message call" do
82
- Thunderer.should_receive(:message).with("chan", "foo").and_return("message")
83
- Thunderer.should_receive(:publish_message).with("message").and_return(:result)
84
- Thunderer.publish_to("chan", "foo").should eq(:result)
90
+ describe '#message' do
91
+
92
+ describe 'formatting' do
93
+ let(:secret_token) { 'token' }
94
+ before { Thunderer.config[:secret_token] = secret_token }
95
+
96
+ subject { Thunderer.message('chan', :foo => 'bar') }
97
+
98
+ it do
99
+ expect(subject).to eq(:ext => {:thunderer_secret_token => 'token'},
100
+ :channel => 'chan',
101
+ :data => {
102
+ :channel => 'chan',
103
+ :data => {:foo => 'bar'}
104
+ })
105
+ end
106
+
107
+ end
108
+
85
109
  end
86
110
 
87
- it "has a Faye rack app instance" do
88
- Thunderer.faye_app.should be_kind_of(Faye::RackAdapter)
111
+ describe '#publish_message' do
112
+ let(:message) { 'foo' }
113
+ subject { Thunderer.publish_message(message) }
114
+
115
+ context 'when config are loaded' do
116
+ before { load_config }
117
+
118
+ specify do
119
+ expect(Thunderer::Messanger).to receive(:post)
120
+ subject
121
+ end
122
+ end
123
+
124
+ context 'when config are not loaded' do
125
+ specify do
126
+ expect { subject }.to raise_error(Thunderer::Error)
127
+ end
128
+ end
129
+
130
+
89
131
  end
90
132
 
91
- it "says signature has expired when time passed in is greater than expiration" do
92
- Thunderer.config[:signature_expiration] = 30*60
93
- time = Thunderer.subscription[:timestamp] - 31*60*1000
94
- Thunderer.signature_expired?(time).should be_true
133
+ describe '#publish_to' do
134
+ let(:message) { 'foo' }
135
+ let(:channel) { 'channel' }
136
+ subject { Thunderer.publish_to(channel, message) }
137
+ before do
138
+ allow(Thunderer).to receive(:message).with( channel, message) { 'message' }
139
+ allow(Thunderer).to receive(:publish_message).with('message') { :result }
140
+ end
141
+
142
+ it { is_expected.to eq(:result)}
143
+
144
+
95
145
  end
96
146
 
97
- it "says signature has not expired when time passed in is less than expiration" do
98
- Thunderer.config[:signature_expiration] = 30*60
99
- time = Thunderer.subscription[:timestamp] - 29*60*1000
100
- Thunderer.signature_expired?(time).should be_false
147
+ describe '#faye_app' do
148
+ subject { Thunderer.faye_app }
149
+
150
+ it { is_expected.to be_kind_of(Faye::RackAdapter) }
151
+
101
152
  end
102
153
 
103
- it "says signature has not expired when expiration is nil" do
104
- Thunderer.config[:signature_expiration] = nil
105
- Thunderer.signature_expired?(0).should be_false
154
+
155
+ describe 'signature_expired?' do
156
+ let(:expiration) { 30*60 }
157
+ before { Thunderer.config[:signature_expiration] = expiration }
158
+ subject { Thunderer.signature_expired?(time) }
159
+
160
+ context 'when time greater than expiration ' do
161
+ let(:time) { Thunderer.subscription[:timestamp] - 31*60*1000 }
162
+
163
+ it { is_expected.to eq(true) }
164
+
165
+ end
166
+
167
+ context 'when time less than expiration' do
168
+ let(:time) { Thunderer.subscription[:timestamp] - 29*60*1000 }
169
+
170
+ it { is_expected.to eq(false) }
171
+
172
+ end
173
+
174
+ context 'when expiration is nil' do
175
+ let(:expiration) { nil }
176
+ let(:time) { 0 }
177
+
178
+ it { is_expected.to eq(nil) }
179
+
180
+ end
181
+
106
182
  end
107
183
 
108
184
  end
data/thunderer.gemspec CHANGED
@@ -17,8 +17,9 @@ Gem::Specification.new do |spec|
17
17
 
18
18
  spec.add_runtime_dependency 'activesupport'
19
19
  spec.add_development_dependency 'rails'
20
- spec.add_development_dependency 'rspec', '~> 2.14.1'
20
+ spec.add_development_dependency 'rspec'
21
21
  spec.add_development_dependency 'jasmine'
22
+ spec.add_development_dependency 'sqlite3'
22
23
 
23
24
  spec.files = `git ls-files -z`.split("\x0")
24
25
  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: 0.9.1
4
+ version: 1.0.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-09-02 00:00:00.000000000 Z
11
+ date: 2014-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faye
@@ -56,16 +56,16 @@ dependencies:
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 2.14.1
61
+ version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 2.14.1
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: jasmine
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
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'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: bundler
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -137,7 +151,10 @@ files:
137
151
  - lib/thunderer/publish_changes.rb
138
152
  - lib/thunderer/version.rb
139
153
  - lib/thunderer/view_helpers.rb
154
+ - spec/fixtures/dummy_classes.yml
155
+ - spec/fixtures/schema.rb
140
156
  - spec/fixtures/thunderer.yml
157
+ - spec/fixtures/thunderer_local_server.yml
141
158
  - spec/javascripts/helpers/.gitkeep
142
159
  - spec/javascripts/helpers/jasmine_examples/SpecHelper.js
143
160
  - spec/javascripts/support/jasmine.yml
@@ -179,7 +196,10 @@ signing_key:
179
196
  specification_version: 4
180
197
  summary: pub/sub messaging in Rails application
181
198
  test_files:
199
+ - spec/fixtures/dummy_classes.yml
200
+ - spec/fixtures/schema.rb
182
201
  - spec/fixtures/thunderer.yml
202
+ - spec/fixtures/thunderer_local_server.yml
183
203
  - spec/javascripts/helpers/.gitkeep
184
204
  - spec/javascripts/helpers/jasmine_examples/SpecHelper.js
185
205
  - spec/javascripts/support/jasmine.yml
@@ -195,3 +215,4 @@ test_files:
195
215
  - spec/thunderer/parser_spec.rb
196
216
  - spec/thunderer/publish_changes_spec.rb
197
217
  - spec/thunderer_spec.rb
218
+ has_rdoc: