montage_rails 0.3.2 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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