fakecrm 0.9.9.beta1

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 (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