xing-backend 0.0.19 → 0.0.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/app/models/role.rb +24 -0
  3. data/config/locales/json.yml +29 -0
  4. data/config/routes.rb +3 -0
  5. data/db/migrate/20140828011806_initial.rb +45 -0
  6. data/db/migrate/20140914030703_devise_token_auth_add_token_info_to_users.rb +20 -0
  7. data/db/migrate/20140929192921_remove_login_from_users.rb +5 -0
  8. data/lib/xing-backend.rb +1 -0
  9. data/lib/xing/engine.rb +4 -0
  10. data/lib/xing/nominal/database_config_validator.rb +31 -0
  11. data/lib/xing/nominal/dependency_utils.rb +26 -0
  12. data/lib/xing/nominal/secrets_validator.rb +50 -0
  13. data/lib/xing/nominal/yaml_config_validator.rb +44 -0
  14. data/lib/xing/services.rb +0 -2
  15. data/lib/xing/services/class_registry.rb +31 -0
  16. data/lib/xing/services/{page_wrapper.rb → paged_wrapper.rb} +2 -2
  17. data/lib/xing/snapshot.rb +4 -0
  18. data/lib/xing/snapshot/domain_helpers.rb +24 -0
  19. data/lib/xing/snapshot/fetcher.rb +35 -0
  20. data/lib/xing/snapshot/local_site_snapshot.rb +37 -0
  21. data/lib/xing/snapshot/remote_site_snapshot.rb +16 -0
  22. data/lib/xing/snapshot/site_page_set.rb +29 -0
  23. data/lib/xing/snapshot/site_snapshot.rb +41 -0
  24. data/lib/xing/snapshot/sitemap.rb +68 -0
  25. data/lib/xing/snapshot/writer.rb +15 -0
  26. data/lib/xing/spec_helpers.rb +7 -0
  27. data/lib/xing/spec_helpers/api_response_matchers.rb +26 -0
  28. data/lib/xing/spec_helpers/ci_support.rb +6 -0
  29. data/lib/xing/spec_helpers/dom_equiv.rb +26 -0
  30. data/lib/xing/spec_helpers/json_requests.rb +58 -0
  31. data/lib/xing/spec_helpers/routing_spec_patch.rb +28 -0
  32. data/lib/xing/spec_helpers/split_servers.rb +15 -0
  33. data/lib/xing/spec_helpers/test_url_helpers.rb +5 -0
  34. data/lib/xing/static.rb +1 -0
  35. data/lib/xing/static/backend_url_cookie.rb +16 -0
  36. data/lib/xing/static/goto_param.rb +30 -0
  37. data/lib/xing/static/logger.rb +11 -0
  38. data/lib/xing/static/rack_app.rb +40 -0
  39. data/lib/xing/tasks/all.rake +4 -0
  40. data/lib/xing/tasks/db_recycle.rake +4 -0
  41. data/lib/xing/tasks/dependencies_common.rake +49 -0
  42. data/lib/xing/tasks/sample_data.rake +49 -0
  43. data/lib/xing/tasks/take_snapshot.rake +4 -0
  44. data/spec/xing/builders/list_builder_spec.rb +0 -2
  45. data/spec/xing/builders/ordered_list_builder_spec.rb +0 -2
  46. data/spec/xing/nominal/database_config_validator_spec.rb +98 -0
  47. data/spec/xing/nominal/secrets_validator_spec.rb +78 -0
  48. data/spec/xing/serializers/list_spec.rb +116 -0
  49. data/spec/xing/serializers/paged_index_spec.rb +2 -2
  50. data/spec/xing/serializers/paged_list_spec.rb +1 -1
  51. data/spec/xing/services/error_converter_spec.rb +1 -3
  52. data/spec/xing/services/paged_wrapper_spec.rb +30 -0
  53. data/spec/xing/snapshot/remote_snapshot_fetcher_spec.rb +81 -0
  54. data/spec/xing/{services → snapshot}/snapshot_fetcher_spec.rb +6 -4
  55. data/spec_help/dummy/db/test.sqlite3 +0 -0
  56. data/spec_help/dummy/log/test.log +143 -0
  57. data/spec_help/file-sandbox.rb +164 -0
  58. data/spec_help/spec_helper.rb +0 -2
  59. metadata +152 -12
  60. data/lib/xing/services/snapshot_fetcher.rb +0 -33
  61. data/lib/xing/services/snapshot_writer.rb +0 -19
@@ -1,5 +1,5 @@
1
1
  require 'xing/serializers/paged_index'
2
- require 'xing/services/page_wrapper'
2
+ require 'xing/services/paged_wrapper'
3
3
 
4
4
  describe Xing::Serializers::PagedIndex do
5
5
  class PageIndexSerializer < Xing::Serializers::PagedIndex
@@ -39,7 +39,7 @@ describe Xing::Serializers::PagedIndex do
39
39
 
40
40
  describe 'as_json' do
41
41
  let :serializer do
42
- PageIndexSerializer.new(Xing::Services::PageWrapper.new(list, page_num, total_items, per_page))
42
+ PageIndexSerializer.new(Xing::Services::PagedWrapper.new(list, page_num, total_items, per_page))
43
43
  end
44
44
 
45
45
  it "should generate a JSON with the proper links and self" do
@@ -42,7 +42,7 @@ describe Xing::Serializers::PagedList do
42
42
  end
43
43
 
44
44
  let :serializer do
45
- PageSerializer.new(Xing::Services::PageWrapper.new(list, page_num, total_items, per_page))
45
+ PageSerializer.new(Xing::Services::PagedWrapper.new(list, page_num, total_items, per_page))
46
46
  end
47
47
 
48
48
  let :json do
@@ -10,9 +10,7 @@ describe Xing::Services::ErrorConverter do
10
10
  before do
11
11
  # ensure that I18n can find the translation file needed for error
12
12
  # conversions
13
- I18n.load_path += Dir[File.join(File.dirname(__FILE__),'../../..', 'config', 'locales', '*.{rb,yml}').tap do |dirn|
14
- puts dirn
15
- end]
13
+ I18n.load_path += Dir[File.join(File.dirname(__FILE__),'../../..', 'config', 'locales', '*.{rb,yml}')]
16
14
  end
17
15
 
18
16
 
@@ -0,0 +1,30 @@
1
+ require 'xing/services/paged_wrapper'
2
+
3
+ describe Xing::Services::PagedWrapper do
4
+ let :list do
5
+ [ :a, :b, :c ]
6
+ end
7
+
8
+ let :per_page do
9
+ 3
10
+ end
11
+
12
+ let :total_items do
13
+ 14
14
+ end
15
+
16
+ let :page_num do
17
+ 2
18
+ end
19
+
20
+ subject :wrapper do
21
+ Xing::Services::PagedWrapper.new(list, page_num, total_items, per_page)
22
+ end
23
+
24
+ it{ expect(subject.current_page).to eq(page_num) }
25
+ it{ expect(subject.total_count).to eq(total_items) }
26
+ it{ expect(subject.limit_value).to eq(per_page) }
27
+
28
+ it{ expect(subject.total_pages).to eq(5) }
29
+ it{ expect(subject.map(&:to_s)).to eq(%w[a b c])}
30
+ end
@@ -0,0 +1,81 @@
1
+ require 'xing/snapshot/fetcher'
2
+ require 'file-sandbox'
3
+
4
+ describe Xing::Snapshot::Fetcher do
5
+ include FileSandbox
6
+
7
+ let :server_secrets do
8
+ { 'url' => 'http://snapshot-server.com',
9
+ 'user' => 'foobar',
10
+ 'password' => 'my_password'
11
+ }
12
+ end
13
+
14
+ before do
15
+ allow(Rails).to receive_message_chain(:application, :secrets, :snapshot_server).and_return(server_secrets)
16
+ allow(Rails).to receive(:root).and_return(@sandbox.root)
17
+ end
18
+
19
+ describe "if remote succeeds" do
20
+ before do
21
+ begin
22
+ #FileUtils.mkdir_p("#{ Rails.root }/spec/fixtures/sitemap_scratch")
23
+ #File.delete("#{ Rails.root }/spec/fixtures/sitemap_scratch/test.html")
24
+ rescue
25
+ end
26
+ end
27
+
28
+ # This feels like way too much mocking, but dont know how to test without
29
+ # completely
30
+ # turning off selenium
31
+ before do
32
+ response = Typhoeus::Response.new(code: 200, body: "some html content")
33
+ Typhoeus.stub(server_secrets['url']).and_return(response)
34
+ expect(Typhoeus::Request).to receive(:new).with(
35
+ server_secrets['url'],
36
+ :userpwd => "#{server_secrets['user']}:#{server_secrets['password']}",
37
+ :params => { :url => "http://www.awesome.com/test" }
38
+ ).and_call_original
39
+ end
40
+
41
+ subject :remote_snapshot_fetcher do
42
+ Xing::Snapshot::Fetcher.new
43
+ end
44
+
45
+ it "should read html contents from remote server and output to the file" do
46
+ remote_snapshot_fetcher.perform("http://www.awesome.com", "test")
47
+ content = File.read("public/frontend_snapshots/test.html")
48
+ expect(content).to eq("some html content")
49
+ end
50
+ end
51
+
52
+ describe "if remote fails" do
53
+ before do
54
+ response = Typhoeus::Response.new(code: 500, status_message: "failed", body: "a backtrace")
55
+ Typhoeus.stub(server_secrets['url']).and_return(response)
56
+ expect(Typhoeus::Request).to receive(:new).with(
57
+ server_secrets['url'],
58
+ :userpwd => "#{server_secrets['user']}:#{server_secrets['password']}",
59
+ :params => { :url => "http://www.awesome.com/test" }
60
+ ).and_call_original
61
+ end
62
+
63
+ let :logger do
64
+ double("Logger")
65
+ end
66
+
67
+ subject :remote_snapshot_fetcher do
68
+ Xing::Snapshot::Fetcher.new.tap do |fetcher|
69
+ allow(fetcher).to receive(:logger).and_return(logger)
70
+ end
71
+ end
72
+
73
+ it "should read html contents from remote server and output to the file" do
74
+ expect(logger).to receive(:warn).with(/failed/)
75
+ expect(logger).to receive(:warn).with(/a backtrace/)
76
+ expect do
77
+ remote_snapshot_fetcher.perform("http://www.awesome.com", "test")
78
+ end.to raise_error(/Query.*failed/)
79
+ end
80
+ end
81
+ end
@@ -1,8 +1,10 @@
1
- require 'xing/services/snapshot_fetcher'
2
- require 'typhoeus'
1
+ require 'xing/snapshot/fetcher'
2
+ require 'file-sandbox'
3
3
 
4
4
 
5
- describe Xing::Services::SnapshotFetcher do
5
+ describe Xing::Snapshot::Fetcher do
6
+ include FileSandbox
7
+
6
8
  let :server_secrets do
7
9
  { 'url' => 'http://snapshot-server.com',
8
10
  'user' => 'foobar',
@@ -13,7 +15,7 @@ describe Xing::Services::SnapshotFetcher do
13
15
  let :mock_request do double('request') end
14
16
  let :mock_response do double('a response') end
15
17
  let :fetcher do
16
- Xing::Services::SnapshotFetcher.new
18
+ Xing::Snapshot::Fetcher.new
17
19
  end
18
20
 
19
21
  before do
File without changes
@@ -0,0 +1,143 @@
1
+ ETHON: Libcurl initialized
2
+ ETHON: started MULTI
3
+ ETHON: performed MULTI
4
+ ETHON: Libcurl initialized
5
+ ETHON: started MULTI
6
+ ETHON: performed MULTI
7
+ ETHON: started MULTI
8
+ ETHON: performed MULTI
9
+ ETHON: Libcurl initialized
10
+ ETHON: started MULTI
11
+ ETHON: performed MULTI
12
+ ETHON: started MULTI
13
+ ETHON: performed MULTI
14
+ ETHON: Libcurl initialized
15
+ ETHON: started MULTI
16
+ ETHON: performed MULTI
17
+ ETHON: started MULTI
18
+ ETHON: performed MULTI
19
+ ETHON: Libcurl initialized
20
+ ETHON: started MULTI
21
+ ETHON: performed MULTI
22
+ ETHON: started MULTI
23
+ ETHON: performed MULTI
24
+ ETHON: Libcurl initialized
25
+ ETHON: started MULTI
26
+ ETHON: performed MULTI
27
+ ETHON: started MULTI
28
+ ETHON: performed MULTI
29
+ ETHON: Libcurl initialized
30
+ ETHON: started MULTI
31
+ ETHON: performed MULTI
32
+ ETHON: started MULTI
33
+ ETHON: performed MULTI
34
+ ETHON: Libcurl initialized
35
+ ETHON: started MULTI
36
+ ETHON: performed MULTI
37
+ ETHON: started MULTI
38
+ ETHON: performed MULTI
39
+ ETHON: Libcurl initialized
40
+ ETHON: started MULTI
41
+ ETHON: performed MULTI
42
+ ETHON: started MULTI
43
+ ETHON: performed MULTI
44
+ ETHON: Libcurl initialized
45
+ ETHON: started MULTI
46
+ ETHON: performed MULTI
47
+ ETHON: started MULTI
48
+ ETHON: performed MULTI
49
+ ETHON: Libcurl initialized
50
+ ETHON: started MULTI
51
+ ETHON: performed MULTI
52
+ ETHON: started MULTI
53
+ ETHON: performed MULTI
54
+ ETHON: Libcurl initialized
55
+ ETHON: started MULTI
56
+ ETHON: performed MULTI
57
+ ETHON: started MULTI
58
+ ETHON: performed MULTI
59
+ ETHON: Libcurl initialized
60
+ ETHON: started MULTI
61
+ ETHON: performed MULTI
62
+ ETHON: started MULTI
63
+ ETHON: performed MULTI
64
+ ETHON: Libcurl initialized
65
+ ETHON: started MULTI
66
+ ETHON: performed MULTI
67
+ ETHON: started MULTI
68
+ ETHON: performed MULTI
69
+ ETHON: Libcurl initialized
70
+ ETHON: started MULTI
71
+ ETHON: performed MULTI
72
+ ETHON: started MULTI
73
+ ETHON: performed MULTI
74
+ ETHON: Libcurl initialized
75
+ ETHON: started MULTI
76
+ ETHON: performed MULTI
77
+ ETHON: started MULTI
78
+ ETHON: performed MULTI
79
+ ETHON: Libcurl initialized
80
+ ETHON: started MULTI
81
+ ETHON: performed MULTI
82
+ ETHON: started MULTI
83
+ ETHON: performed MULTI
84
+ ETHON: Libcurl initialized
85
+ ETHON: started MULTI
86
+ ETHON: performed MULTI
87
+ ETHON: started MULTI
88
+ ETHON: performed MULTI
89
+ ETHON: Libcurl initialized
90
+ ETHON: started MULTI
91
+ ETHON: performed MULTI
92
+ ETHON: started MULTI
93
+ ETHON: performed MULTI
94
+ ETHON: Libcurl initialized
95
+ ETHON: started MULTI
96
+ ETHON: performed MULTI
97
+ ETHON: started MULTI
98
+ ETHON: performed MULTI
99
+ ETHON: Libcurl initialized
100
+ ETHON: started MULTI
101
+ ETHON: performed MULTI
102
+ ETHON: started MULTI
103
+ ETHON: performed MULTI
104
+ ETHON: Libcurl initialized
105
+ ETHON: started MULTI
106
+ ETHON: performed MULTI
107
+ ETHON: started MULTI
108
+ ETHON: performed MULTI
109
+ ETHON: Libcurl initialized
110
+ ETHON: started MULTI
111
+ ETHON: performed MULTI
112
+ ETHON: started MULTI
113
+ ETHON: performed MULTI
114
+ ETHON: Libcurl initialized
115
+ ETHON: started MULTI
116
+ ETHON: performed MULTI
117
+ ETHON: started MULTI
118
+ ETHON: performed MULTI
119
+ ETHON: Libcurl initialized
120
+ ETHON: started MULTI
121
+ ETHON: performed MULTI
122
+ ETHON: started MULTI
123
+ ETHON: performed MULTI
124
+ ETHON: Libcurl initialized
125
+ ETHON: started MULTI
126
+ ETHON: performed MULTI
127
+ ETHON: started MULTI
128
+ ETHON: performed MULTI
129
+ ETHON: Libcurl initialized
130
+ ETHON: started MULTI
131
+ ETHON: performed MULTI
132
+ ETHON: started MULTI
133
+ ETHON: performed MULTI
134
+ ETHON: Libcurl initialized
135
+ ETHON: started MULTI
136
+ ETHON: performed MULTI
137
+ ETHON: started MULTI
138
+ ETHON: performed MULTI
139
+ ETHON: Libcurl initialized
140
+ ETHON: started MULTI
141
+ ETHON: performed MULTI
142
+ ETHON: started MULTI
143
+ ETHON: performed MULTI
@@ -0,0 +1,164 @@
1
+ #require 'ftools'
2
+ require 'fileutils'
3
+
4
+ module FileSandbox
5
+ def self.included(spec)
6
+ return unless spec.respond_to? :before
7
+
8
+ spec.before do
9
+ setup_sandbox
10
+ end
11
+
12
+ spec.after do
13
+ teardown_sandbox
14
+ end
15
+ end
16
+
17
+ class HaveContents
18
+ def initialize(contents)
19
+ @contents = contents
20
+ end
21
+
22
+ def matches?(target)
23
+ case @contents
24
+ when Regexp
25
+ @contents =~ target.contents
26
+ when String
27
+ @contents == target.contents
28
+ end
29
+ end
30
+ end
31
+
32
+ def have_contents(expected)
33
+ HaveContents.new(expected)
34
+ end
35
+
36
+ attr_reader :sandbox
37
+
38
+ def in_sandbox(&block)
39
+ raise "I expected to create a sandbox as you passed in a block to me" if !block_given?
40
+
41
+ setup_sandbox
42
+ original_error = nil
43
+
44
+ begin
45
+ yield @sandbox
46
+ rescue => e
47
+ original_error = e
48
+ raise
49
+ ensure
50
+ begin
51
+ teardown_sandbox
52
+ rescue
53
+ if original_error
54
+ STDERR.puts "ALERT: a test raised an error and failed to release some lock(s) in the sandbox directory"
55
+ raise(original_error)
56
+ else
57
+ raise
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ def setup_sandbox(path = '__sandbox')
64
+ unless @sandbox
65
+ @sandbox = Sandbox.new(path)
66
+ @__old_path_for_sandbox = Dir.pwd
67
+ Dir.chdir(@sandbox.root)
68
+ end
69
+ end
70
+
71
+ def teardown_sandbox
72
+ if @sandbox
73
+ Dir.chdir(@__old_path_for_sandbox)
74
+ @sandbox.clean_up
75
+ @sandbox = nil
76
+ end
77
+ end
78
+
79
+ class Sandbox
80
+ attr_reader :root
81
+
82
+ def initialize(path = '__sandbox')
83
+ @root = File.expand_path(path)
84
+ clean_up
85
+ FileUtils.mkdir_p @root
86
+ end
87
+
88
+ def [](name)
89
+ SandboxFile.new(File.join(@root, name), name)
90
+ end
91
+
92
+ # usage new :file=>'my file.rb', :with_contents=>'some stuff'
93
+ def new(options)
94
+ if options.has_key? :directory
95
+ dir = self[options.delete(:directory)]
96
+ FileUtils.mkdir_p dir.path
97
+ else
98
+ file = self[options.delete(:file)]
99
+ if (binary_content = options.delete(:with_binary_content) || options.delete(:with_binary_contents))
100
+ file.binary_content = binary_content
101
+ else
102
+ file.content = (options.delete(:with_content) || options.delete(:with_contents) || '')
103
+ end
104
+ end
105
+
106
+ raise "unexpected keys '#{options.keys.join(', ')}'" unless options.empty?
107
+
108
+ dir || file
109
+ end
110
+
111
+ def remove(options)
112
+ name = File.join(@root, options[:file])
113
+ FileUtils.remove_file name
114
+ end
115
+
116
+ def clean_up
117
+ FileUtils.rm_rf @root
118
+ if File.exists? @root
119
+ raise "Could not remove directory #{@root.inspect}, something is probably still holding a lock on it"
120
+ end
121
+ end
122
+ end
123
+
124
+
125
+ class SandboxFile
126
+ attr_reader :path
127
+
128
+ def initialize(path, sandbox_path)
129
+ @path = path
130
+ @sandbox_path = sandbox_path
131
+ end
132
+
133
+ def inspect
134
+ "SandboxFile: #@sandbox_path"
135
+ end
136
+
137
+ def exist?
138
+ File.exist? path
139
+ end
140
+
141
+ def content
142
+ File.read path
143
+ end
144
+
145
+ def content=(content)
146
+ FileUtils.mkdir_p File.dirname(@path)
147
+ File.open(@path, "w") {|f| f << content}
148
+ end
149
+
150
+ def binary_content=(content)
151
+ FileUtils.mkdir_p File.dirname(@path)
152
+ File.open(@path, "wb") {|f| f << content}
153
+ end
154
+
155
+ def create
156
+ self.content = ''
157
+ end
158
+
159
+ alias exists? exist?
160
+ alias contents content
161
+ alias contents= content=
162
+ alias binary_contents= binary_content=
163
+ end
164
+ end