fakecrm 0.9.9.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.gitmodules +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +76 -0
  7. data/Rakefile +113 -0
  8. data/bin/fakecrm +37 -0
  9. data/fakecrm.gemspec +34 -0
  10. data/lib/fakecrm/application.rb +85 -0
  11. data/lib/fakecrm/configuration.rb +8 -0
  12. data/lib/fakecrm/drop.rb +59 -0
  13. data/lib/fakecrm/embedded.rb +32 -0
  14. data/lib/fakecrm/fetch.rb +139 -0
  15. data/lib/fakecrm/initialize.rb +16 -0
  16. data/lib/fakecrm/localized_dm.rb +12 -0
  17. data/lib/fakecrm/resource/account.rb +33 -0
  18. data/lib/fakecrm/resource/activity.rb +57 -0
  19. data/lib/fakecrm/resource/contact.rb +51 -0
  20. data/lib/fakecrm/resource/custom_attribute.rb +20 -0
  21. data/lib/fakecrm/resource/custom_type.rb +96 -0
  22. data/lib/fakecrm/resource/event.rb +52 -0
  23. data/lib/fakecrm/resource/event_contact.rb +21 -0
  24. data/lib/fakecrm/resource/extensions/kinds.rb +26 -0
  25. data/lib/fakecrm/resource/extensions/type_extender.rb +42 -0
  26. data/lib/fakecrm/resource/extensions/type_extension.rb +55 -0
  27. data/lib/fakecrm/resource/mailing.rb +30 -0
  28. data/lib/fakecrm/resource/password.rb +17 -0
  29. data/lib/fakecrm/resource/role.rb +18 -0
  30. data/lib/fakecrm/resource/template.rb +41 -0
  31. data/lib/fakecrm/resource/views/resource_view.rb +90 -0
  32. data/lib/fakecrm/resources.rb +11 -0
  33. data/lib/fakecrm/server/accounts.rb +39 -0
  34. data/lib/fakecrm/server/activities.rb +39 -0
  35. data/lib/fakecrm/server/contacts.rb +118 -0
  36. data/lib/fakecrm/server/custom_types.rb +34 -0
  37. data/lib/fakecrm/server/event_contacts.rb +38 -0
  38. data/lib/fakecrm/server/events.rb +47 -0
  39. data/lib/fakecrm/server/mailings.rb +44 -0
  40. data/lib/fakecrm/server/roles.rb +44 -0
  41. data/lib/fakecrm/server/templates.rb +24 -0
  42. data/lib/fakecrm/server.rb +37 -0
  43. data/lib/fakecrm/version.rb +5 -0
  44. data/lib/fakecrm.rb +36 -0
  45. data/locales/de.yml +25 -0
  46. data/locales/en.yml +25 -0
  47. data/test/embedded/.gitignore +15 -0
  48. data/test/embedded/Gemfile +6 -0
  49. data/test/embedded/Rakefile +7 -0
  50. data/test/embedded/app/models/.gitkeep +0 -0
  51. data/test/embedded/config/application.rb +44 -0
  52. data/test/embedded/config/boot.rb +6 -0
  53. data/test/embedded/config/environment.rb +5 -0
  54. data/test/embedded/config/environments/development.rb +20 -0
  55. data/test/embedded/config/environments/test.rb +21 -0
  56. data/test/embedded/config/initializers/fakecrm.rb +8 -0
  57. data/test/embedded/config/initializers/secret_token.rb +7 -0
  58. data/test/embedded/config/initializers/session_store.rb +8 -0
  59. data/test/embedded/config/initializers/wrap_parameters.rb +14 -0
  60. data/test/embedded/config/locales/en.yml +5 -0
  61. data/test/embedded/config/routes.rb +2 -0
  62. data/test/embedded/config.ru +4 -0
  63. data/test/embedded/lib/assets/.gitkeep +0 -0
  64. data/test/embedded/lib/tasks/.gitkeep +0 -0
  65. data/test/embedded/log/.gitkeep +0 -0
  66. data/test/embedded/script/rails +6 -0
  67. metadata +301 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e0d190fc0cf9569dd4eb62f2d843db0febd4fa52
4
+ data.tar.gz: 9ee3ecf7a990ce957dcc1f89df3e53bcc7fb69f4
5
+ SHA512:
6
+ metadata.gz: 493c700aa1763b86db61f308f44e6eb58e9a9aef17b2a89d116667213597a2028e69810f7e7eb8416d58d13c53beec83cd15d803dce05612a6cd2a2fc288f4df
7
+ data.tar.gz: 73a8fbf4a74b10cf364ed8221f1f21a9f2501ee2603c247010ddcce706c89e72bb35a0ba590ff07fa92bfa8a766b5997a2971c453de3ea79a53169ea563dd531
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ lib/db.sqlite
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "test/crm_connector"]
2
+ path = test/crm_connector
3
+ url = git@github.com:infopark/crm_connector.git
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fakecrm.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Mateusz Sojka
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # Fakecrm
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'fakecrm', :git => git@github.com:infopark/fakecrm.git
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ ## Usage
16
+
17
+ You can run this gem as standalone server with:
18
+
19
+ $ fakecrm
20
+
21
+ For help on running this command execute:
22
+
23
+ $ fakecrm --help
24
+
25
+ Another approach is to embed fakecrm directly into your application. The following describes steps neccessary for a rails application.
26
+
27
+ Assuming you added fakecrm to your application's Gemfile, you need to create an initializer, for example under `config/initializers/fakecrm.rb`:
28
+
29
+ # place your Fakecrm configuration here
30
+ Fakecrm::Configuration.silent = true
31
+
32
+ Infopark::Crm.configure do |configuration|
33
+ configuration.url = "http://localhost:#{Fakecrm::Configuration.port}/crm"
34
+ configuration.login = "root"
35
+ configuration.api_key = "deadbeef"
36
+ end
37
+
38
+ require 'fakecrm/embedded'
39
+ Fakecrm.embedded! if Rails.env.development? || Rails.env.test?
40
+
41
+ For available configuration options see the output of the command:
42
+
43
+ $ fakecrm --help
44
+
45
+ ## Testing
46
+
47
+ To prepare test environment execute (you must only do it once):
48
+
49
+ $ git submodule init
50
+ $ git submodule update
51
+
52
+ Execute to update test environment:
53
+
54
+ $ git submodule update
55
+
56
+ Execute this line to run all tests:
57
+
58
+ $ rake
59
+
60
+ Open `coverage/index.html` after running the suite to see a detailed report of code coverage.
61
+
62
+ You can also run only selected test using:
63
+
64
+ $ TEST=test/crm_connector/account_search_custom_field_test.rb rake
65
+
66
+ **Some bugs only become apparent after the suite has been run two consecutive times. To handle this case execute:**
67
+
68
+ $ rake TWICE=1
69
+
70
+ ## Contributing
71
+
72
+ 1. Fork it
73
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
74
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
75
+ 4. Push to the branch (`git push origin my-new-feature`)
76
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,113 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ module Fakecrm
4
+ module SimpleTests
5
+ class Coverage
6
+ def measure
7
+ require 'simplecov'
8
+ SimpleCov.command_name 'test:crm_connector'
9
+ SimpleCov.start
10
+ end
11
+ end
12
+
13
+ class EmbeddedTest
14
+ def app_path
15
+ @app_path ||= File.expand_path('../test/embedded', __FILE__)
16
+ end
17
+
18
+ def configure
19
+ File.open(File.join(app_path, 'config/initializers/fakecrm.rb'), 'w') do |f|
20
+ f.puts <<-EOF
21
+ Infopark::Crm.configure do |configuration|
22
+ configuration.url = "http://localhost:\#{Fakecrm::Configuration.port}/crm"
23
+ configuration.login = "root"
24
+ configuration.api_key = "deadbeef"
25
+ end
26
+
27
+ require 'fakecrm/embedded'
28
+ Fakecrm.embedded! if Rails.env.development? || Rails.env.test?
29
+ EOF
30
+ end
31
+ end
32
+
33
+ def test
34
+ Dir.chdir(app_path)
35
+ `bundle > /dev/null && bundle exec rails runner "fail '' unless Infopark::Crm::Contact.search(:params => {:login => 'root'}).first.login == 'root'"`
36
+ raise "Embedded test failed" unless $?.success?
37
+ end
38
+
39
+ def run
40
+ $stdout.puts "Running embedded tests"
41
+ configure
42
+ test
43
+ $stdout.puts "Embedded tests successful"
44
+ end
45
+ end
46
+
47
+ class ConnectorTest
48
+ def crm_path
49
+ @crm_path ||= File.expand_path('../test/crm_connector', __FILE__)
50
+ end
51
+
52
+ def load_fakecrm
53
+ require File.expand_path('../lib/fakecrm', __FILE__)
54
+ require File.expand_path('../lib/fakecrm/embedded', __FILE__)
55
+ end
56
+
57
+ def configure_connector
58
+ File.open(File.join(crm_path,'test/local_config.rb'), 'w') do |f|
59
+ f.write <<-EOS
60
+ require 'helpful_configuration'
61
+ require 'json'
62
+
63
+ def either_file(*files)
64
+ found = files.detect do |file|
65
+ File.exists?(file)
66
+ end
67
+ raise "Could not find any of the files \#{files.join(', ')}" unless found
68
+ found
69
+ end
70
+
71
+ def local_config
72
+ {
73
+ "login" => "root",
74
+ "api_key" => "deadbeef",
75
+ "url" => "http://localhost:#{Fakecrm::Configuration.port}/crm"
76
+ }
77
+ end
78
+ EOS
79
+ end
80
+ end
81
+ def test
82
+ Dir.chdir(crm_path)
83
+ load File.join(crm_path, 'Rakefile')
84
+ Rake::Task["test"].invoke
85
+ Rake::Task["test"].execute if ENV['TWICE']
86
+ end
87
+
88
+ def start_embedded_server
89
+ require 'fakecrm/embedded'
90
+ port, pid = Fakecrm.embedded!
91
+ Fakecrm::Configuration.port = port
92
+ end
93
+
94
+ def run
95
+ load_fakecrm
96
+ start_embedded_server
97
+ configure_connector
98
+ $stdout.puts "Running connector tests"
99
+ test
100
+ $stdout.puts "Connector tests successful"
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ desc "Tests the gem"
107
+ task :testrun do
108
+ Fakecrm::SimpleTests::Coverage.new.measure unless ENV['TEST']
109
+ Fakecrm::SimpleTests::EmbeddedTest.new.run unless ENV['TEST']
110
+ Fakecrm::SimpleTests::ConnectorTest.new.run
111
+ end
112
+
113
+ task :default => :testrun
data/bin/fakecrm ADDED
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'rubygems'
5
+ require 'bundler'
6
+ require 'bundler/setup'
7
+
8
+ begin
9
+ require 'fakecrm'
10
+ rescue LoadError => e
11
+ require File.expand_path('../../lib/fakecrm', __FILE__)
12
+ end
13
+
14
+ conf = Fakecrm::Configuration
15
+ OptionParser.new do |opts|
16
+ opts.banner = "Usage: fakecrm [options]"
17
+
18
+ opts.on("-s", "--silent", "Run silently (disable any output)") do |s|
19
+ conf.silent = true
20
+ end
21
+
22
+ opts.on("-l", "--log-level [LEVEL]", [:fatal, :error, :warn, :info, :debug], "Select log level (off, fatal, error, warn, info, debug, default=#{conf.log_level})") do |l|
23
+ conf.log_level = l
24
+ end
25
+
26
+ opts.on("-p", "--port [PORT]", OptionParser::DecimalNumeric, "Select port to run on (default #{conf.port})") do |p|
27
+ conf.port = p
28
+ end
29
+
30
+ opts.on("-d", "--database [DATABASE", "Setup database to use fakecrm with, for example:", "#{conf.database} (default)", "mysql://user:password@hostname/database","postgres://user:password@hostname/database") do |d|
31
+ conf.database = d
32
+ end
33
+
34
+ end.parse!
35
+
36
+
37
+ Fakecrm.run!
data/fakecrm.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'fakecrm/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "fakecrm"
8
+ spec.version = Fakecrm::VERSION
9
+ spec.authors = ["Mateusz Sojka", "Tomasz Przedmojski"]
10
+ spec.email = ["mateusz.sojka@infopark.de", "tomasz.przedmojski@infopark.de"]
11
+ spec.description = %q{FakeCRM is a mock implementation for the Infopark WebCRM. It can be used for offline local development and automated testing.}
12
+ spec.summary = %q{FakeCRM is a mock implementation for the Infopark WebCRM.}
13
+ spec.homepage = "https://github.com/infopark/fakecrm"
14
+ spec.license = "LGPLv3"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "pry"
24
+ spec.add_development_dependency "byebug"
25
+ spec.add_development_dependency "simplecov"
26
+ spec.add_dependency 'dm-sqlite-adapter'
27
+ spec.add_dependency 'json'
28
+ spec.add_dependency 'sinatra'
29
+ spec.add_dependency 'rack-contrib'
30
+ spec.add_dependency 'thin'
31
+ spec.add_dependency 'i18n'
32
+ spec.add_dependency 'data_mapper'
33
+ end
34
+
@@ -0,0 +1,85 @@
1
+ require 'fakecrm/configuration'
2
+ require 'fakecrm/server'
3
+
4
+ module Fakecrm
5
+ class Application
6
+ include Singleton
7
+
8
+ def configure
9
+ configure_logger
10
+ configure_dm
11
+ configure_server
12
+ end
13
+
14
+ def configure_logger
15
+ level_map = {
16
+ :info => Logger::INFO,
17
+ :debug => Logger::DEBUG,
18
+ :warn => Logger::WARN,
19
+ :error => Logger::ERROR,
20
+ :fatal => Logger::FATAL
21
+ }
22
+
23
+ if Configuration.silent
24
+ Thin::Logging.silent = true
25
+ DataMapper::Logger.new($stderr, :fatal)
26
+ self.logger = Logger.new(nil)
27
+ else
28
+ DataMapper::Logger.new($stderr, Configuration.log_level)
29
+ self.logger = Logger.new($stderr, level_map[Configuration.log_level])
30
+ end
31
+
32
+ # replace sinatra logger
33
+ Fakecrm::Server.disable :logging
34
+ Fakecrm::Server.use Rack::CommonLogger, self.logger
35
+ end
36
+
37
+ def load_and_initialize
38
+ logger.debug("Loading resources")
39
+ require 'fakecrm/resources'
40
+ logger.debug("Initializing resources")
41
+ require 'fakecrm/initialize'
42
+ end
43
+
44
+ def configure_dm
45
+ logger.debug("Configuring default database to: #{Configuration.database}")
46
+ DataMapper.setup(:default, Configuration.database)
47
+ logger.debug("Configuring localizations")
48
+ I18n.load_path += Dir[File.join(File.dirname(__FILE__), '../../locales', '*.yml').to_s]
49
+ logger.debug("Using i18n files: #{I18n.load_path.inspect}")
50
+ require 'fakecrm/localized_dm'
51
+ end
52
+
53
+ def configure_server
54
+ logger.debug("Configuring server to run on port #{Configuration.port}")
55
+ Fakecrm::Server.set :port, Configuration.port
56
+ logger.debug("Switching do production environment")
57
+ Fakecrm::Server.set :environment, :production
58
+ end
59
+
60
+ def prepare!
61
+ configure
62
+ load_and_initialize
63
+ end
64
+
65
+ def run!
66
+ prepare!
67
+ start_server
68
+ end
69
+
70
+ def start_server
71
+ Fakecrm::Server.run!
72
+ end
73
+
74
+ def logger
75
+ if !@logger
76
+ $stderr.puts("Warning: Logger has not been configured! Defaulting to nil logger")
77
+ self.logger = Logger.new(nil)
78
+ end
79
+ @logger
80
+ end
81
+
82
+ protected
83
+ attr_writer :logger
84
+ end
85
+ end
@@ -0,0 +1,8 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'singleton'
3
+ module Fakecrm
4
+ Configuration = Struct
5
+ .new(:database, :port, :log_level, :silent)
6
+ .new("sqlite3:///tmp/fakecrm.sqlite3", 3276, :debug, false)
7
+ end
8
+
@@ -0,0 +1,59 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Fakecrm
3
+ module Drop
4
+ def create_one(resource, data)
5
+ response = {}
6
+ resource.transaction do |t|
7
+ instance = resource.new
8
+ instance.attributes = data
9
+
10
+ if instance.save
11
+ response = instance
12
+ else
13
+ status 422
14
+ response = instance.errors.to_hash
15
+ end
16
+ end
17
+
18
+ response.to_json
19
+ rescue ArgumentError => e
20
+ status 422
21
+ ::Fakecrm.logger.error("Unable to set unknown attribute: #{e.inspect}")
22
+ {:error => "Unknown attribute"}.to_json
23
+ end
24
+
25
+ def update_one(resource, primary_key, data)
26
+ response = {}
27
+ resource.transaction do |t|
28
+ instance = resource.get!(primary_key)
29
+ ::Fakecrm.logger.debug("Updating resource with: #{data.inspect}")
30
+ instance.attributes = data
31
+ if instance.save
32
+ response = {}
33
+ else
34
+ status 422
35
+ ::Fakecrm.logger.debug("Updating resouce failed: #{instance.errors.to_hash.inspect}")
36
+ response = instance.errors.to_hash
37
+ end
38
+ end
39
+
40
+ body response.to_json
41
+ rescue ::DataMapper::ObjectNotFoundError
42
+ status 404
43
+ rescue ArgumentError => e
44
+ status 422
45
+ ::Fakecrm.logger.error("Unable to set unknown attribute: #{e.inspect}")
46
+ {:error => "Unknown attribute"}.to_json
47
+ end
48
+
49
+ def destroy_one(resource, primary_key)
50
+ resource.transaction do |t|
51
+ resource.get!(primary_key).destroy
52
+ end
53
+ body {}.to_json
54
+ rescue ::DataMapper::ObjectNotFoundError
55
+ status 404
56
+ end
57
+ end
58
+ end
59
+
@@ -0,0 +1,32 @@
1
+ module Fakecrm
2
+ def self.embedded!
3
+ require 'fakecrm/configuration'
4
+
5
+ port = 4000 + rand(10000)
6
+ url = "http://localhost:#{port}/crm"
7
+
8
+ if defined?(Infopark::Crm)
9
+ Infopark::Crm.configure do |configuration|
10
+ configuration.url = url
11
+ configuration.login = "root"
12
+ configuration.api_key = "deadbeef"
13
+ end
14
+ end
15
+
16
+ pid = fork do
17
+ require 'fakecrm'
18
+ Fakecrm::Configuration.port = port
19
+ Fakecrm::Configuration.database = 'sqlite::memory:'
20
+ Fakecrm::Configuration.silent = true
21
+ self.run!
22
+ exit!
23
+ end
24
+ sleep(1)
25
+ at_exit do
26
+ Process.kill("INT", pid)
27
+ Process.wait(pid)
28
+ end
29
+
30
+ return [port, pid]
31
+ end
32
+ end
@@ -0,0 +1,139 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'fakecrm/resource/views/resource_view'
3
+
4
+ module Fakecrm
5
+ module Fetch
6
+ def continuation
7
+ JSON.parse(Base64.decode64(params.fetch("continuation_handle", "e30=")))
8
+ rescue => exception
9
+ {}
10
+ end
11
+
12
+ def build_continuation
13
+ Base64.urlsafe_encode64(params.merge({:offset => offset+limit, :limit => limit, :include_deleted => include_deleted?.to_s}).to_json)
14
+ end
15
+
16
+ def limit
17
+ limit = params.fetch("limit", continuation.fetch("limit", "10")).to_i
18
+ (1..1000).include?(limit) ? limit : 10
19
+ end
20
+
21
+ def offset
22
+ continuation.fetch("offset", 0).to_i
23
+ end
24
+
25
+ def include_deleted?
26
+ "true" == continuation.fetch("include_deleted", params.fetch("include_deleted", "false")).to_s
27
+ end
28
+
29
+ def consider_deleted(resource)
30
+ if include_deleted?
31
+ resource.with_deleted
32
+ else
33
+ resource
34
+ end
35
+ end
36
+
37
+
38
+ def search(resource, builtins=[], full_text_fields=[], sort_by = nil, sort_order = 'asc')
39
+ options = {}
40
+ builtins.each do |built_in_field|
41
+ options[built_in_field.to_sym] = params[built_in_field.to_s] if params.key?(built_in_field.to_s)
42
+
43
+ end
44
+
45
+ custom_fields = []
46
+ resource.properties.each do |property|
47
+ custom_fields << property.name if property.name =~ /^custom/
48
+ end
49
+
50
+ # custom fields
51
+ params.each do |key, value|
52
+ if key =~ /^custom_/
53
+ options[key] = value
54
+ elsif key =~ /_id$/
55
+ # cast ids to integers
56
+ options[key.to_sym] = value.to_i
57
+ end
58
+ end
59
+
60
+ # full text
61
+ if params.key?('q')
62
+ fields = []
63
+ values = []
64
+ (full_text_fields + custom_fields).each do |full_text_field|
65
+ queries = params['q'].split(/\s/)
66
+
67
+ sub_fields = []
68
+ queries.each do |query|
69
+ sub_fields << "(#{full_text_field} LIKE ?)"
70
+ values << "%#{query}%"
71
+ end
72
+ fields << (" ( " + sub_fields.join(" OR ") + " ) ") unless sub_fields.empty?
73
+ end
74
+ if !fields.empty?
75
+ options[:conditions] = [fields.join(' OR ')] + values
76
+ end
77
+ end
78
+
79
+ # Reject empty options to mimic WebCRM
80
+ options = options.reject { |_, value| value.nil? || value == '' }
81
+
82
+ query = resource.all(options)
83
+ # FIXME: code duplication (fetch_many)
84
+ total_count = query.count
85
+ remaining_count = total_count - offset
86
+
87
+ query_options = { :limit => limit, :offset => offset }
88
+
89
+ if sort_by
90
+ sort_order ||= 'asc'
91
+ sort_order = 'asc' unless ['asc', 'desc'].include?(sort_order.downcase)
92
+ if sort_by.to_sym == :updated_at
93
+ order = { :order => [sort_by.to_sym.send(sort_order.to_sym), :id.send(sort_order.to_sym)] }
94
+ else
95
+ order = { :order => sort_by.to_sym.send(sort_order.to_sym) }
96
+ end
97
+
98
+ query_options.merge!(order)
99
+ end
100
+
101
+ result = {:results => query.all(query_options), :total => total_count}
102
+
103
+ if remaining_count > limit
104
+ result["continuation_handle"] = build_continuation
105
+ end
106
+
107
+ status 200
108
+ body result.to_json
109
+ end
110
+
111
+ def fetch_many(resource)
112
+ query = consider_deleted(resource)
113
+ remaining_count = query.count - offset
114
+ result = {:results => ResourceView.decorate(query.all(:limit => limit, :offset => offset)) }
115
+
116
+ if remaining_count > limit
117
+ result["continuation_handle"] = build_continuation
118
+ end
119
+
120
+ status 200
121
+ body result.to_json
122
+ end
123
+
124
+ def fetch_one(resource, primary_key)
125
+ begin
126
+ status 200
127
+ if resource.respond_to? :with_deleted
128
+ body ResourceView.decorate(resource.with_deleted.get!(primary_key)).to_json
129
+ else
130
+ body ResourceView.decorate(resource.get!(primary_key)).to_json
131
+ end
132
+ rescue ::DataMapper::ObjectNotFoundError => e
133
+ status 404
134
+ end
135
+ end
136
+
137
+ end
138
+ end
139
+
@@ -0,0 +1,16 @@
1
+ # -*- encoding : utf-8 -*-
2
+ DataMapper.auto_upgrade!
3
+
4
+ contact = Fakecrm::Contact.first_or_create(:last_name => 'root', :login => 'root', :gender => 'N', :language => 'en', :email => 'root@root.org')
5
+ Fakecrm::Password.first_or_create(:password => 'root', :contact => contact)
6
+
7
+
8
+ Fakecrm::CustomType.first_or_create(:name => 'contact', :kind => 'Contact')
9
+
10
+ Fakecrm::CustomType.first_or_create(:name => 'account', :kind => 'Account')
11
+
12
+ Fakecrm::CustomType.all.each do |custom_type|
13
+ Fakecrm::TypeExtender.new(custom_type).extend!
14
+ end
15
+
16
+
@@ -0,0 +1,12 @@
1
+ class DataMapper::Validations::ValidationErrors
2
+ def self.default_error_message(key, field, *values)
3
+ begin
4
+ message = I18n.t!(:"messages.#{key}")
5
+ rescue
6
+ ::Fakecrm.logger.debug("Translation for message key #{key} not found (locale=#{I18n.locale})")
7
+ message = @@default_error_messages[key]
8
+ end
9
+ field = DataMapper::Inflector.humanize(field)
10
+ message % [field, *values].flatten
11
+ end
12
+ end