aws-sessionstore-dynamodb 1.0.0 → 2.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.
Files changed (50) hide show
  1. checksums.yaml +5 -5
  2. data/.github/PULL_REQUEST_TEMPLATE.md +6 -0
  3. data/.gitignore +1 -0
  4. data/.gitmodules +3 -0
  5. data/.travis.yml +16 -5
  6. data/.yardopts +3 -2
  7. data/CHANGELOG.md +24 -0
  8. data/CODE_OF_CONDUCT.md +4 -0
  9. data/CONTRIBUTING.md +61 -0
  10. data/Gemfile +7 -19
  11. data/{LICENSE.txt → LICENSE} +0 -0
  12. data/README.md +17 -63
  13. data/Rakefile +37 -14
  14. data/VERSION +1 -0
  15. data/aws-sessionstore-dynamodb.gemspec +7 -5
  16. data/doc-src/templates/default/layout/html/footer.erb +10 -0
  17. data/doc-src/templates/default/layout/html/layout.erb +31 -0
  18. data/lib/aws-sessionstore-dynamodb.rb +0 -15
  19. data/lib/aws/session_store/dynamo_db/configuration.rb +2 -29
  20. data/lib/aws/session_store/dynamo_db/errors/base_handler.rb +0 -14
  21. data/lib/aws/session_store/dynamo_db/errors/default_handler.rb +0 -14
  22. data/lib/aws/session_store/dynamo_db/garbage_collection.rb +2 -15
  23. data/lib/aws/session_store/dynamo_db/invalid_id_error.rb +0 -14
  24. data/lib/aws/session_store/dynamo_db/lock_wait_timeout_error.rb +0 -14
  25. data/lib/aws/session_store/dynamo_db/locking/base.rb +14 -17
  26. data/lib/aws/session_store/dynamo_db/locking/null.rb +0 -14
  27. data/lib/aws/session_store/dynamo_db/locking/pessimistic.rb +0 -16
  28. data/lib/aws/session_store/dynamo_db/missing_secret_key_error.rb +0 -14
  29. data/lib/aws/session_store/dynamo_db/rack_middleware.rb +11 -24
  30. data/lib/aws/session_store/dynamo_db/table.rb +1 -14
  31. data/lib/aws/session_store/dynamo_db/version.rb +1 -15
  32. data/spec/aws/session_store/dynamo_db/app_config.yml +6 -6
  33. data/spec/aws/session_store/dynamo_db/configuration_spec.rb +28 -51
  34. data/spec/aws/session_store/dynamo_db/error/default_error_handler_spec.rb +23 -21
  35. data/spec/aws/session_store/dynamo_db/garbage_collection_spec.rb +68 -69
  36. data/spec/aws/session_store/dynamo_db/locking/threaded_sessions_spec.rb +17 -16
  37. data/spec/aws/session_store/dynamo_db/rack_middleware_database_spec.rb +47 -46
  38. data/spec/aws/session_store/dynamo_db/rack_middleware_spec.rb +59 -61
  39. data/spec/aws/session_store/dynamo_db/table_spec.rb +9 -7
  40. data/spec/spec_helper.rb +14 -11
  41. metadata +27 -29
  42. data/lib/aws/session_store/dynamo_db/railtie.rb +0 -28
  43. data/lib/aws/session_store/dynamo_db/tasks/session_table.rake +0 -21
  44. data/lib/rails/generators/sessionstore/dynamodb/dynamodb_generator.rb +0 -55
  45. data/lib/rails/generators/sessionstore/dynamodb/templates/sessionstore/USAGE +0 -13
  46. data/lib/rails/generators/sessionstore/dynamodb/templates/sessionstore/dynamodb.yml +0 -71
  47. data/lib/rails/generators/sessionstore/dynamodb/templates/sessionstore_migration.rb +0 -10
  48. data/spec/aws/session_store/dynamo_db/config/dynamo_db_session.yml +0 -24
  49. data/spec/aws/session_store/dynamo_db/rails_app_config.yml +0 -24
  50. data/tasks/test.rake +0 -29
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
4
  #
3
5
  # Licensed under the Apache License, Version 2.0 (the "License"). You
@@ -11,7 +13,6 @@
11
13
  # ANY KIND, either express or implied. See the License for the specific
12
14
  # language governing permissions and limitations under the License.
13
15
 
14
-
15
16
  require 'spec_helper'
16
17
 
17
18
  describe Aws::SessionStore::DynamoDB do
@@ -20,43 +21,44 @@ describe Aws::SessionStore::DynamoDB do
20
21
  instance_exec(&ConstantHelpers)
21
22
 
22
23
  before do
23
- @options = { :dynamo_db_client => client, :secret_key => 'meltingbutter' }
24
+ @options = { dynamo_db_client: client, secret_key: 'meltingbutter' }
24
25
  end
25
26
 
26
27
  let(:base_app) { MultiplierApplication.new }
27
28
  let(:app) { Aws::SessionStore::DynamoDB::RackMiddleware.new(base_app, @options) }
28
29
  let(:client) { double('Aws::DynamoDB::Client') }
29
30
 
30
- context "Error handling for Rack Middleware with default error handler" do
31
- it "raises error for missing secret key" do
32
- client.stub(:update_item).and_raise(missing_key_error)
33
- lambda { get "/" }.should raise_error(missing_key_error)
31
+ context 'Error handling for Rack Middleware with default error handler' do
32
+ it 'raises error for missing secret key' do
33
+ allow(client).to receive(:update_item).and_raise(missing_key_error)
34
+ expect { get '/' }.to raise_error(missing_key_error)
34
35
  end
35
36
 
36
- it "catches exception for inaccurate table name and raises error " do
37
- client.stub(:update_item).and_raise(resource_error)
38
- lambda { get "/" }.should raise_error(resource_error)
37
+ it 'catches exception for inaccurate table name and raises error ' do
38
+ allow(client).to receive(:update_item).and_raise(resource_error)
39
+ expect { get '/' }.to raise_error(resource_error)
39
40
  end
40
41
 
41
- it "catches exception for inaccurate table key" do
42
- client.stub(:update_item).and_raise(key_error)
43
- client.stub(:get_item).and_raise(key_error)
44
- get "/"
45
- last_request.env["rack.errors"].string.should include(key_error_msg)
42
+ it 'catches exception for inaccurate table key' do
43
+ allow(client).to receive(:update_item).and_raise(key_error)
44
+ allow(client).to receive(:get_item).and_raise(key_error)
45
+
46
+ get '/'
47
+ expect(last_request.env['rack.errors'].string).to include(key_error_msg)
46
48
  end
47
49
  end
48
50
 
49
- context "Test ExceptionHandler with true as return value for handle_error" do
50
- it "raises all errors" do
51
+ context 'Test ExceptionHandler with true as return value for handle_error' do
52
+ it 'raises all errors' do
51
53
  @options[:raise_errors] = true
52
- client.stub(:update_item).and_raise(client_error)
53
- lambda { get "/" }.should raise_error(client_error)
54
+ allow(client).to receive(:update_item).and_raise(client_error)
55
+ expect { get '/' }.to raise_error(client_error)
54
56
  end
55
57
 
56
- it "catches exception for inaccurate table key and raises error" do
58
+ it 'catches exception for inaccurate table key and raises error' do
57
59
  @options[:raise_errors] = true
58
- client.stub(:update_item).and_raise(key_error)
59
- lambda { get "/" }.should raise_error(key_error)
60
+ allow(client).to receive(:update_item).and_raise(key_error)
61
+ expect { get '/' }.to raise_error(key_error)
60
62
  end
61
63
  end
62
64
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
4
  #
3
5
  # Licensed under the Apache License, Version 2.0 (the "License"). You
@@ -14,80 +16,79 @@
14
16
  require 'spec_helper'
15
17
 
16
18
  describe Aws::SessionStore::DynamoDB::GarbageCollection do
17
- def member(min,max)
18
- member = []
19
- for i in min..max
20
- member << {"session_id"=>{:s=>"#{i}"}}
19
+ def items(min, max)
20
+ items = []
21
+ (min..max).each do |i|
22
+ items << { 'session_id' => { s: i.to_s } }
21
23
  end
22
- member
24
+ items
23
25
  end
24
26
 
25
27
  def format_scan_result
26
- member = []
27
- for i in 31..49
28
- member << {"session_id"=>{:s=>"#{i}"}}
28
+ items = []
29
+ (31..49).each do |i|
30
+ items << { 'session_id' => { s: i.to_s } }
29
31
  end
30
32
 
31
- member.inject([]) do |rqst_array, item|
32
- rqst_array << {:delete_request => {:key => item}}
33
- rqst_array
33
+ items.each_with_object([]) do |item, rqst_array|
34
+ rqst_array << { delete_request: { key: item } }
34
35
  end
35
36
  end
36
37
 
37
38
  def collect_garbage
38
- options = { :dynamo_db_client => dynamo_db_client, :max_age => 100, :max_stale => 100 }
39
+ options = { dynamo_db_client: dynamo_db_client, max_age: 100, max_stale: 100 }
39
40
  Aws::SessionStore::DynamoDB::GarbageCollection.collect_garbage(options)
40
41
  end
41
42
 
42
- let(:scan_resp1){
43
+ let(:scan_resp1) do
43
44
  resp = {
44
- :member => member(0, 49),
45
- :count => 50,
46
- :scanned_count => 1000,
47
- :last_evaluated_key => {}
45
+ items: items(0, 49),
46
+ count: 50,
47
+ scanned_count: 1000,
48
+ last_evaluated_key: {}
48
49
  }
49
- }
50
+ end
50
51
 
51
- let(:scan_resp2){
52
+ let(:scan_resp2) do
52
53
  {
53
- :member => member(0, 31),
54
- :last_evaluated_key => {"session_id"=>{:s=>"31"}}
54
+ items: items(0, 31),
55
+ last_evaluated_key: { 'session_id' => { s: '31' } }
55
56
  }
56
- }
57
+ end
57
58
 
58
- let(:scan_resp3){
59
+ let(:scan_resp3) do
59
60
  {
60
- :member => member(31,49),
61
- :last_evaluated_key => {}
61
+ items: items(31, 49),
62
+ last_evaluated_key: {}
62
63
  }
63
- }
64
+ end
64
65
 
65
- let(:write_resp1){
66
+ let(:write_resp1) do
66
67
  {
67
- :unprocessed_items => {}
68
+ unprocessed_items: {}
68
69
  }
69
- }
70
+ end
70
71
 
71
- let(:write_resp2){
72
+ let(:write_resp2) do
72
73
  {
73
- :unprocessed_items => {
74
- "sessions" => [
74
+ unprocessed_items: {
75
+ 'sessions' => [
75
76
  {
76
- :delete_request => {
77
- :key => {
78
- "session_id" =>
77
+ delete_request: {
78
+ key: {
79
+ 'session_id' =>
79
80
  {
80
- :s => "1"
81
+ s: '1'
81
82
  }
82
83
  }
83
84
  }
84
85
  },
85
86
  {
86
- :delete_request => {
87
- :key => {
88
- "session_id" =>
87
+ delete_request: {
88
+ key: {
89
+ 'session_id' =>
89
90
  {
90
- :s => "17"
91
+ s: '17'
91
92
  }
92
93
  }
93
94
  }
@@ -95,64 +96,62 @@ describe Aws::SessionStore::DynamoDB::GarbageCollection do
95
96
  ]
96
97
  }
97
98
  }
98
- }
99
+ end
99
100
 
100
101
  let(:dynamo_db_client) {Aws::DynamoDB::Client.new}
101
102
 
102
- context "Mock DynamoDB client with garbage collection" do
103
-
104
- it "processes scan result greater than 25 and deletes in batches of 25" do
105
- dynamo_db_client.should_receive(:scan).
106
- exactly(1).times.and_return(scan_resp1)
107
- dynamo_db_client.should_receive(:batch_write_item).
103
+ context 'Mock DynamoDB client with garbage collection' do
104
+ it 'processes scan result greater than 25 and deletes in batches of 25' do
105
+ expect(dynamo_db_client).to receive(:scan)
106
+ .exactly(1).times.and_return(scan_resp1)
107
+ expect(dynamo_db_client).to receive(:batch_write_item).
108
108
  exactly(2).times.and_return(write_resp1)
109
109
  collect_garbage
110
110
  end
111
111
 
112
- it "gets scan results then returns last evaluated key and resumes scanning" do
113
- dynamo_db_client.should_receive(:scan).
112
+ it 'gets scan results then returns last evaluated key and resumes scanning' do
113
+ expect(dynamo_db_client).to receive(:scan).
114
114
  exactly(1).times.and_return(scan_resp2)
115
- dynamo_db_client.should_receive(:scan).
115
+ expect(dynamo_db_client).to receive(:scan).
116
116
  exactly(1).times.with(hash_including(exclusive_start_key: scan_resp2[:last_evaluated_key])).
117
117
  and_return(scan_resp3)
118
- dynamo_db_client.should_receive(:batch_write_item).
118
+ expect(dynamo_db_client).to receive(:batch_write_item).
119
119
  exactly(3).times.and_return(write_resp1)
120
- collect_garbage
120
+ collect_garbage
121
121
  end
122
122
 
123
- it "it formats unprocessed_items and then batch deletes them" do
124
- dynamo_db_client.should_receive(:scan).
123
+ it 'it formats unprocessed_items and then batch deletes them' do
124
+ expect(dynamo_db_client).to receive(:scan).
125
125
  exactly(1).times.and_return(scan_resp3)
126
- dynamo_db_client.should_receive(:batch_write_item).ordered.
127
- with(:request_items => {"sessions" => format_scan_result}).
126
+ expect(dynamo_db_client).to receive(:batch_write_item).ordered.
127
+ with(request_items: { 'sessions' => format_scan_result }).
128
128
  and_return(write_resp2)
129
- dynamo_db_client.should_receive(:batch_write_item).ordered.with(
130
- :request_items =>
131
- {
132
- "sessions" => [
129
+ expect(dynamo_db_client).to receive(:batch_write_item).ordered.with(
130
+ request_items: {
131
+ 'sessions' => [
133
132
  {
134
- :delete_request => {
135
- :key => {
136
- "session_id" =>
133
+ delete_request: {
134
+ key: {
135
+ 'session_id' =>
137
136
  {
138
- :s => "1"
137
+ s: '1'
139
138
  }
140
139
  }
141
140
  }
142
141
  },
143
142
  {
144
- :delete_request => {
145
- :key => {
146
- "session_id" =>
143
+ delete_request: {
144
+ key: {
145
+ 'session_id' =>
147
146
  {
148
- :s => "17"
147
+ s: '17'
149
148
  }
150
149
  }
151
150
  }
152
151
  }
153
152
  ]
154
153
  }
155
- ).and_return(write_resp1)
154
+ ).and_return(write_resp1)
156
155
  collect_garbage
157
156
  end
158
157
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
4
  #
3
5
  # Licensed under the Apache License, Version 2.0 (the "License"). You
@@ -11,7 +13,6 @@
11
13
  # ANY KIND, either express or implied. See the License for the specific
12
14
  # language governing permissions and limitations under the License.
13
15
 
14
-
15
16
  require 'spec_helper'
16
17
 
17
18
  describe Aws::SessionStore::DynamoDB::RackMiddleware do
@@ -20,17 +21,17 @@ describe Aws::SessionStore::DynamoDB::RackMiddleware do
20
21
  def thread(mul_val, time, check)
21
22
  Thread.new do
22
23
  sleep(time)
23
- get "/"
24
- last_request.session[:multiplier].should eq(mul_val) if check
24
+ get '/'
25
+ expect(last_request.session[:multiplier]).to eq(mul_val) if check
25
26
  end
26
27
  end
27
28
 
28
29
  def thread_exception(error)
29
- Thread.new { expect { get "/" }.to raise_error(error) }
30
+ Thread.new { expect { get '/' }.to raise_error(error) }
30
31
  end
31
32
 
32
33
  def update_item_mock(options, update_method)
33
- if options[:return_values] == "UPDATED_NEW" && options.has_key?(:expected)
34
+ if options[:return_values] == 'UPDATED_NEW' && options.key?(:expected)
34
35
  sleep(0.50)
35
36
  update_method.call(options)
36
37
  else
@@ -41,23 +42,23 @@ describe Aws::SessionStore::DynamoDB::RackMiddleware do
41
42
  let(:base_app) { MultiplierApplication.new }
42
43
  let(:app) { Aws::SessionStore::DynamoDB::RackMiddleware.new(base_app, @options) }
43
44
 
44
- context "Mock Multiple Threaded Sessions", :integration => true do
45
+ context 'Mock Multiple Threaded Sessions', integration: true do
45
46
  before do
46
47
  @options = Aws::SessionStore::DynamoDB::Configuration.new.to_hash
47
48
  @options[:enable_locking] = true
48
49
  @options[:secret_key] = 'watermelon_smiles'
49
50
 
50
51
  update_method = @options[:dynamo_db_client].method(:update_item)
51
- @options[:dynamo_db_client].should_receive(:update_item).at_least(:once) do |options|
52
+ expect(@options[:dynamo_db_client]).to receive(:update_item).at_least(:once) do |options|
52
53
  update_item_mock(options, update_method)
53
54
  end
54
55
  end
55
56
 
56
- it "should wait for lock" do
57
+ it 'should wait for lock' do
57
58
  @options[:lock_expiry_time] = 2000
58
59
 
59
- get "/"
60
- last_request.session[:multiplier].should eq(1)
60
+ get '/'
61
+ expect(last_request.session[:multiplier]).to eq(1)
61
62
 
62
63
  t1 = thread(2, 0, false)
63
64
  t2 = thread(4, 0.25, true)
@@ -65,11 +66,11 @@ describe Aws::SessionStore::DynamoDB::RackMiddleware do
65
66
  t2.join
66
67
  end
67
68
 
68
- it "should bust lock" do
69
+ it 'should bust lock' do
69
70
  @options[:lock_expiry_time] = 100
70
71
 
71
- get "/"
72
- last_request.session[:multiplier].should eq(1)
72
+ get '/'
73
+ expect(last_request.session[:multiplier]).to eq(1)
73
74
 
74
75
  t1 = thread_exception(Aws::DynamoDB::Errors::ConditionalCheckFailedException)
75
76
  t2 = thread(2, 0.25, true)
@@ -77,13 +78,13 @@ describe Aws::SessionStore::DynamoDB::RackMiddleware do
77
78
  t2.join
78
79
  end
79
80
 
80
- it "should throw exceeded time spent aquiring lock error" do
81
+ it 'should throw exceeded time spent aquiring lock error' do
81
82
  @options[:lock_expiry_time] = 1000
82
83
  @options[:lock_retry_delay] = 100
83
84
  @options[:lock_max_wait_time] = 0.25
84
85
 
85
- get "/"
86
- last_request.session[:multiplier].should eq(1)
86
+ get '/'
87
+ expect(last_request.session[:multiplier]).to eq(1)
87
88
 
88
89
  t1 = thread(2, 0, false)
89
90
  sleep(0.25)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
4
  #
3
5
  # Licensed under the Apache License, Version 2.0 (the "License"). You
@@ -22,28 +24,28 @@ module Aws
22
24
  instance_exec(&ConstantHelpers)
23
25
 
24
26
  before do
25
- @options = { :secret_key => 'watermelon_cherries' }
27
+ @options = { secret_key: 'watermelon_cherries' }
26
28
  end
27
29
 
28
30
  # Table options for client
29
31
  def table_opts(sid)
30
32
  {
31
- :table_name => Configuration::DEFAULTS[:table_name],
32
- :key => { Configuration::DEFAULTS[:table_key] => sid }
33
+ table_name: Configuration::DEFAULTS[:table_name],
34
+ key: { Configuration::DEFAULTS[:table_key] => sid }
33
35
  }
34
36
  end
35
37
 
36
38
  # Attributes to be retrieved via client
37
39
  def attr_opts
38
40
  {
39
- :attributes_to_get => ["data", "created_at", "locked_at"],
40
- :consistent_read => true
41
+ attributes_to_get: %w[data created_at locked_at],
42
+ consistent_read: true
41
43
  }
42
44
  end
43
45
 
44
46
  def extract_time(sid)
45
47
  options = table_opts(sid).merge(attr_opts)
46
- Time.at((client.get_item(options)[:item]["created_at"]).to_f)
48
+ Time.at((client.get_item(options)[:item]['created_at']).to_f)
47
49
  end
48
50
 
49
51
  let(:base_app) { MultiplierApplication.new }
@@ -51,76 +53,75 @@ module Aws
51
53
  let(:config) { Configuration.new }
52
54
  let(:client) { config.dynamo_db_client }
53
55
 
54
- context "Testing best case session storage", :integration => true do
55
- it "stores session data in session object" do
56
- get "/"
57
- last_request.session[:multiplier].should eq(1)
56
+ context 'Testing best case session storage', integration: true do
57
+ it 'stores session data in session object' do
58
+ get '/'
59
+ expect(last_request.session[:multiplier]).to eq(1)
58
60
  end
59
61
 
60
- it "creates a new HTTP cookie when Cookie not supplied" do
61
- get "/"
62
- last_response.body.should eq('All good!')
63
- last_response['Set-Cookie'].should be_truthy
62
+ it 'creates a new HTTP cookie when Cookie not supplied' do
63
+ get '/'
64
+ expect(last_response.body).to eq('All good!')
65
+ expect(last_response['Set-Cookie']).to be_truthy
64
66
  end
65
67
 
66
- it "does not rewrite Cookie if cookie previously/accuarately set" do
67
- get "/"
68
- last_response['Set-Cookie'].should_not be_nil
69
-
68
+ it 'does not rewrite Cookie if cookie previously/accuarately set' do
69
+ get '/'
70
+ expect(last_response['Set-Cookie']).not_to be_nil
70
71
 
71
- get "/"
72
- last_response['Set-Cookie'].should be_nil
72
+ get '/'
73
+ expect(last_response['Set-Cookie']).to be_nil
73
74
  end
74
75
 
75
- it "does not set cookie when defer option is specifed" do
76
+ it 'does not set cookie when defer option is specified' do
76
77
  @options[:defer] = true
77
- get "/"
78
- last_response['Set-Cookie'].should be_nil
78
+ get '/'
79
+ expect(last_response['Set-Cookie']).to be_nil
79
80
  end
80
81
 
81
- it "creates new sessopm with false/nonexistant http-cookie id" do
82
- get "/", {}, invalid_cookie.merge(invalid_session_data)
83
- last_response['Set-Cookie'].should_not eq("rack.session=ApplePieBlueberries")
84
- last_response['Set-Cookie'].should_not be_nil
82
+ it 'creates new session with false/nonexistant http-cookie id' do
83
+ get '/', {}, invalid_cookie.merge(invalid_session_data)
84
+ expect(last_response['Set-Cookie']).not_to eq('rack.session=ApplePieBlueberries')
85
+ expect(last_response['Set-Cookie']).not_to be_nil
85
86
  end
86
87
 
87
- it "expires after specified time and sets date for cookie to expire" do
88
+ it 'expires after specified time and sets date for cookie to expire' do
88
89
  @options[:expire_after] = 1
89
- get "/"
90
+ get '/'
90
91
  session_cookie = last_response['Set-Cookie']
91
92
  sleep(1.2)
92
93
 
93
- get "/"
94
- last_response['Set-Cookie'].should_not be_nil
95
- last_response['Set-Cookie'].should_not eq(session_cookie)
94
+ get '/'
95
+ expect(last_response['Set-Cookie']).not_to be_nil
96
+ expect(last_response['Set-Cookie']).not_to eq(session_cookie)
96
97
  end
97
98
 
98
- it "will not set a session cookie when defer is true" do
99
+ it 'will not set a session cookie when defer is true' do
99
100
  @options[:defer] = true
100
- get "/"
101
- last_response['Set-Cookie'].should eq(nil)
101
+ get '/'
102
+ expect(last_response['Set-Cookie']).to be_nil
102
103
  end
103
104
 
104
- it "adds the created at attribute for a new session" do
105
- get "/"
106
- last_request.env["dynamo_db.new_session"].should eq("true")
105
+ it 'adds the created at attribute for a new session' do
106
+ get '/'
107
+ expect(last_request.env['dynamo_db.new_session']).to eq('true')
107
108
  sid = last_response['Set-Cookie'].split(/[;\=]/)[1]
108
109
  time = extract_time(sid)
109
- time.should be_within(2).of(Time.now)
110
+ expect(time).to be_within(2).of(Time.now)
110
111
 
111
- get "/"
112
- last_request.env['dynamo_db.new_session'].should be(nil)
112
+ get '/'
113
+ expect(last_request.env['dynamo_db.new_session']).to be_nil
113
114
  end
114
115
 
115
- it "releases pessimistic lock at finish of transaction" do
116
+ it 'releases pessimistic lock at finish of transaction' do
116
117
  @options[:enable_locking] = true
117
- get "/"
118
- last_request.env["dynamo_db.new_session"].should eq("true")
118
+ get '/'
119
+ expect(last_request.env['dynamo_db.new_session']).to eq('true')
119
120
  sid = last_response['Set-Cookie'].split(/[;\=]/)[1]
120
121
 
121
- get "/"
122
+ get '/'
122
123
  options = table_opts(sid).merge(attr_opts)
123
- client.get_item(options)[:item]["locked_at"].should be_nil
124
+ expect(client.get_item(options)[:item]['locked_at']).to be_nil
124
125
  end
125
126
  end
126
127
  end