montage_rails 0.3.2 → 0.4.1

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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +28 -0
  4. data/lib/montage_rails/base/column.rb +57 -0
  5. data/lib/montage_rails/base.rb +406 -0
  6. data/lib/montage_rails/errors.rb +7 -0
  7. data/lib/montage_rails/log_subscriber.rb +48 -0
  8. data/lib/montage_rails/query_cache.rb +44 -0
  9. data/lib/montage_rails/railtie.rb +0 -0
  10. data/lib/montage_rails/relation.rb +88 -0
  11. data/lib/montage_rails/version.rb +3 -0
  12. data/lib/montage_rails.rb +57 -0
  13. data/lib/tasks/montage_rails_tasks.rake +4 -0
  14. data/test/dummy/README.rdoc +28 -0
  15. data/test/dummy/Rakefile +6 -0
  16. data/test/dummy/app/assets/javascripts/application.js +13 -0
  17. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  18. data/test/dummy/app/controllers/application_controller.rb +5 -0
  19. data/test/dummy/app/helpers/application_helper.rb +2 -0
  20. data/test/dummy/app/models/actor.rb +3 -0
  21. data/test/dummy/app/models/movie.rb +30 -0
  22. data/test/dummy/app/models/studio.rb +3 -0
  23. data/test/dummy/app/models/test.rb +2 -0
  24. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  25. data/test/dummy/bin/bundle +3 -0
  26. data/test/dummy/bin/rails +4 -0
  27. data/test/dummy/bin/rake +4 -0
  28. data/test/dummy/bin/setup +29 -0
  29. data/test/dummy/config/application.rb +25 -0
  30. data/test/dummy/config/boot.rb +5 -0
  31. data/test/dummy/config/database.yml +25 -0
  32. data/test/dummy/config/environment.rb +5 -0
  33. data/test/dummy/config/environments/development.rb +41 -0
  34. data/test/dummy/config/environments/production.rb +79 -0
  35. data/test/dummy/config/environments/test.rb +42 -0
  36. data/test/dummy/config/initializers/assets.rb +11 -0
  37. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  38. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  39. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  40. data/test/dummy/config/initializers/inflections.rb +16 -0
  41. data/test/dummy/config/initializers/mime_types.rb +4 -0
  42. data/test/dummy/config/initializers/montage.rb +4 -0
  43. data/test/dummy/config/initializers/session_store.rb +3 -0
  44. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  45. data/test/dummy/config/locales/en.yml +23 -0
  46. data/test/dummy/config/routes.rb +56 -0
  47. data/test/dummy/config/secrets.yml +22 -0
  48. data/test/dummy/config.ru +4 -0
  49. data/test/dummy/db/development.sqlite3 +0 -0
  50. data/test/dummy/db/schema.rb +16 -0
  51. data/test/dummy/db/test.sqlite3 +0 -0
  52. data/test/dummy/log/RAILS_ENV=development.log +0 -0
  53. data/test/dummy/log/development.log +1038 -0
  54. data/test/dummy/log/test.log +12368 -0
  55. data/test/dummy/public/404.html +67 -0
  56. data/test/dummy/public/422.html +67 -0
  57. data/test/dummy/public/500.html +66 -0
  58. data/test/dummy/public/favicon.ico +0 -0
  59. data/test/montage_rails/base/column_test.rb +59 -0
  60. data/test/montage_rails/base_test.rb +375 -0
  61. data/test/montage_rails/query_cache_test.rb +68 -0
  62. data/test/montage_rails/relation_test.rb +114 -0
  63. data/test/montage_rails_test.rb +97 -0
  64. data/test/resources/actor_resource.rb +141 -0
  65. data/test/resources/movie_resource.rb +160 -0
  66. data/test/resources/studio_resource.rb +56 -0
  67. data/test/test_helper.rb +196 -0
  68. metadata +123 -3
@@ -0,0 +1,114 @@
1
+ require 'test_helper'
2
+ require 'montage_rails/base'
3
+ require 'montage_rails/relation'
4
+
5
+ class MontageRails::RelationTest < Minitest::Test
6
+ context "#paginate" do
7
+ setup do
8
+ @movie = MontageRails::Relation.new(Movie).where(title: "The Jerk").limit(1)
9
+ end
10
+
11
+ context "when will paginate is defined" do
12
+ setup do
13
+ require 'will_paginate/collection'
14
+ Object.send(:remove_const, :Kaminari) if Object.const_defined?("Kaminari")
15
+ end
16
+
17
+ should "return a will paginate collection" do
18
+ assert_equal "WillPaginate::Collection", @movie.paginate.class.name
19
+ end
20
+ end
21
+
22
+ context "when kaminari is defined" do
23
+ setup do
24
+ require 'kaminari'
25
+ Kaminari::Hooks.init
26
+ Object.send(:remove_const, :WillPaginate) if Object.const_defined?("WillPaginate")
27
+ end
28
+
29
+ should "return a Kaminari collection" do
30
+ assert_equal "Kaminari::PaginatableArray", @movie.paginate.class.name
31
+ end
32
+ end
33
+
34
+ context "when no paginator is defined" do
35
+ should "return self" do
36
+ assert_equal @movie.first.attributes, @movie.paginate.first.attributes
37
+ end
38
+ end
39
+ end
40
+
41
+ context "#reset" do
42
+ setup do
43
+ @movie = MontageRails::Relation.new(Movie).where(title: "The Jerk").limit(1)
44
+ end
45
+
46
+ should "reset all the values" do
47
+ @movie.reset
48
+
49
+ assert !@movie.loaded?
50
+ end
51
+
52
+ should "only remove the query for that relation from the cache" do
53
+ @movie.cache.get_or_set_query("foo", "bar") do
54
+ "bar"
55
+ end
56
+
57
+ @movie.reset
58
+
59
+ assert_nil @movie.cache.cache["Movie/{:filter=>{:title=>\"The Jerk\"}, :limit=>1}"]
60
+ assert_equal "bar", @movie.cache.cache["foo/bar"]
61
+ end
62
+ end
63
+
64
+ context "#reload" do
65
+ setup do
66
+ @movie = MontageRails::Relation.new(Movie).where(title: "The Jerk").limit(1)
67
+ end
68
+
69
+ should "reset the values and reload the relation" do
70
+ @movie.reload
71
+
72
+ assert !@movie.to_a.empty?
73
+ end
74
+ end
75
+
76
+ context "#to_json" do
77
+ setup do
78
+ @relation = MontageRails::Relation.new(Movie)
79
+ end
80
+
81
+ should "parse the relation to a json format" do
82
+ assert_equal "{\"filter\":{\"foo\":1.0,\"bar__gt\":2},\"order_by\":\"created_at\",\"ordering\":\"desc\",\"limit\":10}", @relation.where(foo: 1.0).where("bar > 2").order(created_at: :desc).limit(10).to_json
83
+ end
84
+ end
85
+
86
+ context "#to_a" do
87
+ should "return the record set without a query if the records have already been fetched" do
88
+ @relation = MontageRails::Relation.new(Movie)
89
+
90
+ @r = @relation.where("votes > 900000")
91
+ @r.to_a
92
+
93
+ assert @r.loaded?
94
+ end
95
+
96
+ should "query the remote db and return the record set if the records have not already been fetched" do
97
+ @movies = MontageRails::Relation.new(Movie).where("votes > 900000").to_a
98
+
99
+ assert_equal 1, @movies.count
100
+ end
101
+ end
102
+
103
+ context "#inspect" do
104
+ setup do
105
+ @movie = MontageRails::Relation.new(Movie).where(title: "The Jerk").limit(1)
106
+ end
107
+
108
+ should "call to_a and inspect" do
109
+ @movie.expects(:to_a).returns(stub(inspect: []))
110
+
111
+ @movie.inspect
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,97 @@
1
+ require 'test_helper'
2
+
3
+ class MontageRailsTest < ActiveSupport::TestCase
4
+ context ".configure" do
5
+ setup do
6
+ MontageRails.username = nil
7
+ MontageRails.password = nil
8
+ MontageRails.token = nil
9
+ MontageRails.domain = nil
10
+ end
11
+
12
+ teardown do
13
+ MontageRails.configure do |c|
14
+ c.token = "fb761e07-a12b-40bb-a42f-2202ecfd1046"
15
+ c.domain = "testco"
16
+ end
17
+ end
18
+
19
+ should "accept a username, password, token, and domain" do
20
+ MontageRails.configure do |c|
21
+ c.username = "darin"
22
+ c.password = "foo"
23
+ c.token = "bar"
24
+ c.domain = "test"
25
+ end
26
+
27
+ assert_equal "darin", MontageRails.username
28
+ assert_equal "foo", MontageRails.password
29
+ assert_equal "bar", MontageRails.token
30
+ assert_equal "test", MontageRails.domain
31
+ end
32
+
33
+ should "require a domain" do
34
+ assert_raises(MontageRails::AttributeMissingError, "You must include a domain") do
35
+ MontageRails.configure do |c|
36
+ c.username = "darin"
37
+ c.password = "foo"
38
+ end
39
+ end
40
+ end
41
+
42
+ should "require a username and password if no token is given" do
43
+ assert_raises(MontageRails::AttributeMissingError, "You must include a username and password if no token is given") do
44
+ MontageRails.configure do |c|
45
+ c.domain = "foo"
46
+ end
47
+ end
48
+ end
49
+
50
+ should "not require a username and password if a token is given" do
51
+ MontageRails.configure do |c|
52
+ c.domain = "foo"
53
+ c.token = "bar"
54
+ end
55
+ end
56
+
57
+ should "call the auth method and retrieve the token if it has not been set" do
58
+ c = Montage::Client.new do |c|
59
+ c.domain = "foo"
60
+ c.username = "bar"
61
+ c.password = "foobar"
62
+ end
63
+
64
+ Montage::Client.expects(:new).returns(c)
65
+
66
+ c.expects(:auth).returns(Montage::Response.new(200, { "data" => { "token" => "foobar" } }, "token"))
67
+
68
+ MontageRails.configure do |c|
69
+ c.domain = "foo"
70
+ c.username = "darin"
71
+ c.password = "foo"
72
+ end
73
+
74
+ assert_equal "foobar", MontageRails.token
75
+ end
76
+
77
+ should "raise an exception if authentication fails" do
78
+ c = Montage::Client.new do |c|
79
+ c.domain = "foo"
80
+ c.username = "bar"
81
+ c.password = "foobar"
82
+ end
83
+
84
+ Montage::Client.expects(:new).returns(c)
85
+
86
+ c.expects(:auth).returns(Montage::Response.new(404, { "data" => [] }))
87
+
88
+ assert_raises(MontageRails::MontageAPIError, "There was a problem authenticating with your username and password for domain foo") do
89
+ MontageRails.configure do |c|
90
+ c.domain = "foo"
91
+ c.username = "darin"
92
+ c.password = "bar"
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,141 @@
1
+ module MontageRails
2
+ class ActorResource
3
+ def self.schema_definition
4
+ {
5
+ name: "actors",
6
+ fields: [
7
+ {
8
+ name: "movie_id",
9
+ datatype: "text",
10
+ indexed: false,
11
+ required: false
12
+ },
13
+ {
14
+ name: "name",
15
+ datatype: "text",
16
+ indexed: false,
17
+ required: true
18
+ }
19
+ ],
20
+ links: {
21
+ self: "http://testco.dev.montagehot.club/api/v1/schemas/actors/",
22
+ query: "http://testco.dev.montagehot.club/api/v1/schemas/actors/query/",
23
+ create_document: "http://testco.dev.montagehot.club/api/v1/schemas/actors/save/"
24
+ }
25
+ }
26
+ end
27
+
28
+ def self.steve_martin
29
+ {
30
+ movie_id: "69cc93af-1f0e-43bc-ac9a-19117111978e",
31
+ name: "Steve Martin"
32
+ }
33
+ end
34
+
35
+ def self.mark_hamill
36
+ {
37
+ movie_id: nil,
38
+ name: "Mark Hamill"
39
+ }
40
+ end
41
+
42
+ def self.save_steve_response
43
+ {
44
+ data: [
45
+ {
46
+ id: "2b427e93-4809-425b-a587-e309a4715e8f",
47
+ _meta: {
48
+ modified: "2015-04-20T18:39:53.628Z",
49
+ created: "2015-04-20T18:39:53.628Z"
50
+ },
51
+ movie_id: "69cc93af-1f0e-43bc-ac9a-19117111978e",
52
+ name: "Steve Martin"
53
+ }
54
+ ]
55
+ }
56
+ end
57
+
58
+ def self.save_mark_response
59
+ {
60
+ data: [
61
+ {
62
+ id: "d8332c5b-71a9-423d-8bc8-9d956e7257a4",
63
+ _meta: {
64
+ modified: "2015-04-20T18:39:53.962Z",
65
+ created: "2015-04-20T18:39:53.962Z"
66
+ },
67
+ movie_id: "",
68
+ name: "Mark Hamill"
69
+ }
70
+ ]
71
+ }
72
+ end
73
+
74
+ def self.query
75
+ {
76
+ filter: {
77
+ movie_id: "69cc93af-1f0e-43bc-ac9a-19117111978e" ,
78
+ name: "Steve Martin"
79
+ },
80
+ limit: 1
81
+ }
82
+ end
83
+
84
+ def self.query_result
85
+ {
86
+ data: [
87
+ {
88
+ id: "2b427e93-4809-425b-a587-e309a4715e8f",
89
+ _meta: {
90
+ modified: "2015-04-20T18:39:53.628Z",
91
+ created: "2015-04-20T18:39:53.628Z"
92
+ },
93
+ movie_id: "69cc93af-1f0e-43bc-ac9a-19117111978e",
94
+ name: "Steve Martin"
95
+ }
96
+ ],
97
+ cursors: {
98
+ previous: nil,
99
+ next: nil
100
+ }
101
+ }
102
+ end
103
+
104
+ def self.relation_query
105
+ {
106
+ filter: {
107
+ movie_id: "69cc93af-1f0e-43bc-ac9a-19117111978e"
108
+ }
109
+ }
110
+ end
111
+
112
+ def self.relation_response
113
+ {
114
+ data: [
115
+ {
116
+ id: "2b427e93-4809-425b-a587-e309a4715e8f",
117
+ _meta: {
118
+ modified: "2015-04-20T18:39:53.628Z",
119
+ created: "2015-04-20T18:39:53.628Z"
120
+ },
121
+ movie_id: "69cc93af-1f0e-43bc-ac9a-19117111978e",
122
+ name: "Steve Martin"
123
+ }
124
+ ],
125
+ cursors: {
126
+ previous: nil,
127
+ next: nil
128
+ }
129
+ }
130
+ end
131
+
132
+ def self.relation_first_query
133
+ {
134
+ filter: {
135
+ movie_id: "69cc93af-1f0e-43bc-ac9a-19117111978e"
136
+ },
137
+ limit: 1
138
+ }
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,160 @@
1
+ module MontageRails
2
+ class MovieResource
3
+ def self.schema_definition
4
+ {
5
+ name: "movies",
6
+ fields: [
7
+ {name: "studio_id", datatype: "text", indexed: false, required: false},
8
+ {name: "rank", datatype: "numeric", indexed: false, required: true},
9
+ {name: "rating", datatype: "numeric", indexed: false, required: true},
10
+ {name: "title", datatype: "text", indexed: false, required: true},
11
+ {name: "votes", datatype: "numeric", indexed: false, required: true},
12
+ {name: "year", datatype: "numeric", indexed: false, required: true}
13
+ ],
14
+ links: {
15
+ query: "http://testco.dev.montagehot.club/api/v1/schemas/movies/query/",
16
+ self: "http://testco.dev.montagehot.club/api/v1/schemas/movies/",
17
+ create_document: "http://testco.dev.montagehot.club/api/v1/schemas/movies/save/"
18
+ }
19
+ }
20
+ end
21
+
22
+ def self.to_hash
23
+ {
24
+ studio_id: "19442e09-5c2d-4e5d-8f34-675570e81414",
25
+ rank: 4,
26
+ rating: 2.0,
27
+ title: "The Jerk",
28
+ votes: 500,
29
+ year: 1983
30
+ }
31
+ end
32
+
33
+ def self.save_with_update_hash
34
+ {
35
+ id: nil,
36
+ studio_id: "19442e09-5c2d-4e5d-8f34-675570e81414",
37
+ rank: 4,
38
+ rating: 2.0,
39
+ title: "The Jerk",
40
+ votes: 500,
41
+ year: 1983
42
+ }
43
+ end
44
+
45
+ def self.update_body
46
+ [
47
+ {
48
+ id: "69cc93af-1f0e-43bc-ac9a-19117111978e",
49
+ studio_id: "19442e09-5c2d-4e5d-8f34-675570e81414",
50
+ rank: 4,
51
+ rating: 2.0,
52
+ title: "The Jerk",
53
+ votes: 600,
54
+ year: 1983
55
+ }
56
+ ]
57
+ end
58
+
59
+ def self.save_response
60
+ {
61
+ data: [
62
+ {
63
+ votes: 500,
64
+ _meta: {
65
+ modified: "2015-04-20T18:39:47.751Z",
66
+ created: "2015-04-20T18:39:47.751Z"
67
+ },
68
+ rating: 2.0,
69
+ year: 1983,
70
+ id: "69cc93af-1f0e-43bc-ac9a-19117111978e",
71
+ title:"The Jerk",
72
+ rank: 4,
73
+ studio_id: "19442e09-5c2d-4e5d-8f34-675570e81414"
74
+ }
75
+ ]
76
+ }
77
+ end
78
+
79
+ def self.update_response
80
+ {
81
+ data: [
82
+ {
83
+ votes: 600,
84
+ _meta: {
85
+ modified: "2015-04-20T18:39:47.751Z",
86
+ created: "2015-04-20T18:39:47.751Z"
87
+ },
88
+ rating: 2.0,
89
+ year: 1983,
90
+ id: "69cc93af-1f0e-43bc-ac9a-19117111978e",
91
+ title:"The Jerk",
92
+ rank: 4,
93
+ studio_id: "19442e09-5c2d-4e5d-8f34-675570e81414"
94
+ }
95
+ ]
96
+ }
97
+ end
98
+
99
+ def self.movie_query
100
+ {
101
+ filter: {
102
+ title: "The Jerk"
103
+ },
104
+ limit: 1
105
+ }
106
+ end
107
+
108
+ def self.query_result
109
+ {
110
+ data: [
111
+ {
112
+ _meta: {
113
+ modified: "2015-04-20T18:39:50.095Z",
114
+ created: "2015-04-20T18:39:47.751Z"
115
+ },
116
+ votes: 600,
117
+ rating: 2.0,
118
+ year: 1983,
119
+ id: "69cc93af-1f0e-43bc-ac9a-19117111978e",
120
+ title: "The Jerk",
121
+ rank: 4,
122
+ studio_id: "19442e09-5c2d-4e5d-8f34-675570e81414"
123
+ }
124
+ ],
125
+ cursors: {
126
+ previous: nil,
127
+ next: nil
128
+ }
129
+ }
130
+ end
131
+
132
+ def self.find_movie_query
133
+ {
134
+ filter: {
135
+ title: "The Jerk"
136
+ }
137
+ }
138
+ end
139
+
140
+ def self.movie_not_found_query
141
+ {
142
+ filter: {
143
+ title: "Foo"
144
+ }
145
+ }
146
+ end
147
+
148
+ def self.all_movies_query
149
+ { filter: {} }
150
+ end
151
+
152
+ def self.gt_query
153
+ {
154
+ filter: {
155
+ votes__gt: 900000
156
+ }
157
+ }
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,56 @@
1
+ module MontageRails
2
+ class StudioResource
3
+ def self.schema_definition
4
+ {
5
+ name: "studios",
6
+ fields: [
7
+ {
8
+ name: "name",
9
+ datatype: "text",
10
+ indexed: false,
11
+ required: true
12
+ }
13
+ ],
14
+ links: {
15
+ self: "http://testco.dev.montagehot.club/api/v1/schemas/studios/",
16
+ query: "http://testco.dev.montagehot.club/api/v1/schemas/studios/query/",
17
+ create_document: "http://testco.dev.montagehot.club/api/v1/schemas/studios/save/"
18
+ }
19
+ }
20
+ end
21
+
22
+ def self.to_hash
23
+ {
24
+ name: "Universal"
25
+ }
26
+ end
27
+
28
+ def self.save_response
29
+ {
30
+ data: [
31
+ {
32
+ id: "19442e09-5c2d-4e5d-8f34-675570e81414",
33
+ _meta: {
34
+ modified: "2015-04-20T18:39:51.394Z",
35
+ created: "2015-04-20T18:39:51.394Z"
36
+ },
37
+ name: "Universal"
38
+ }
39
+ ]
40
+ }
41
+ end
42
+
43
+ def self.get_studio_response
44
+ {
45
+ data: {
46
+ id: "19442e09-5c2d-4e5d-8f34-675570e81414",
47
+ _meta: {
48
+ modified: "2015-04-20T18:39:51.394Z",
49
+ created: "2015-04-20T18:39:51.394Z"
50
+ },
51
+ name: "Universal"
52
+ }
53
+ }
54
+ end
55
+ end
56
+ end