parse-stack-next 4.5.0
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.
- checksums.yaml +7 -0
- data/.bundle/config +2 -0
- data/.env.sample +112 -0
- data/.env.test +10 -0
- data/.github/workflows/ruby.yml +36 -0
- data/.gitignore +49 -0
- data/.ruby-version +1 -0
- data/.solargraph.yml +22 -0
- data/CHANGELOG.md +5816 -0
- data/Gemfile +30 -0
- data/Gemfile.lock +175 -0
- data/LICENSE.txt +23 -0
- data/Makefile +63 -0
- data/README.md +5655 -0
- data/Rakefile +573 -0
- data/bin/console +38 -0
- data/bin/parse-console +136 -0
- data/bin/server +17 -0
- data/bin/setup +7 -0
- data/config/parse-config.json +12 -0
- data/docs/TEST_SERVER.md +271 -0
- data/docs/_config.yml +1 -0
- data/docs/mcp_guide.md +3484 -0
- data/docs/mongodb_direct_guide.md +1348 -0
- data/docs/mongodb_index_optimization_guide.md +631 -0
- data/examples/transaction_example.rb +219 -0
- data/lib/parse/acl_scope.rb +728 -0
- data/lib/parse/agent/cancellation_token.rb +80 -0
- data/lib/parse/agent/constraint_translator.rb +480 -0
- data/lib/parse/agent/describe.rb +420 -0
- data/lib/parse/agent/errors.rb +133 -0
- data/lib/parse/agent/mcp_client.rb +557 -0
- data/lib/parse/agent/mcp_dispatcher.rb +1023 -0
- data/lib/parse/agent/mcp_rack_app.rb +1143 -0
- data/lib/parse/agent/mcp_server.rb +376 -0
- data/lib/parse/agent/metadata_audit.rb +259 -0
- data/lib/parse/agent/metadata_dsl.rb +733 -0
- data/lib/parse/agent/metadata_registry.rb +794 -0
- data/lib/parse/agent/pipeline_validator.rb +82 -0
- data/lib/parse/agent/prompts.rb +351 -0
- data/lib/parse/agent/rate_limiter.rb +158 -0
- data/lib/parse/agent/relation_graph.rb +162 -0
- data/lib/parse/agent/result_formatter.rb +453 -0
- data/lib/parse/agent/tools.rb +5489 -0
- data/lib/parse/agent.rb +3249 -0
- data/lib/parse/api/aggregate.rb +79 -0
- data/lib/parse/api/all.rb +26 -0
- data/lib/parse/api/analytics.rb +18 -0
- data/lib/parse/api/batch.rb +33 -0
- data/lib/parse/api/cloud_functions.rb +58 -0
- data/lib/parse/api/config.rb +125 -0
- data/lib/parse/api/files.rb +29 -0
- data/lib/parse/api/hooks.rb +117 -0
- data/lib/parse/api/objects.rb +146 -0
- data/lib/parse/api/path_segment.rb +75 -0
- data/lib/parse/api/push.rb +20 -0
- data/lib/parse/api/schema.rb +49 -0
- data/lib/parse/api/server.rb +50 -0
- data/lib/parse/api/sessions.rb +24 -0
- data/lib/parse/api/users.rb +250 -0
- data/lib/parse/atlas_search/index_manager.rb +353 -0
- data/lib/parse/atlas_search/result.rb +204 -0
- data/lib/parse/atlas_search/search_builder.rb +604 -0
- data/lib/parse/atlas_search/session.rb +253 -0
- data/lib/parse/atlas_search.rb +995 -0
- data/lib/parse/client/authentication.rb +97 -0
- data/lib/parse/client/batch.rb +234 -0
- data/lib/parse/client/body_builder.rb +240 -0
- data/lib/parse/client/caching.rb +203 -0
- data/lib/parse/client/logging.rb +293 -0
- data/lib/parse/client/profiling.rb +181 -0
- data/lib/parse/client/protocol.rb +91 -0
- data/lib/parse/client/request.rb +233 -0
- data/lib/parse/client/response.rb +208 -0
- data/lib/parse/client.rb +1104 -0
- data/lib/parse/clp_scope.rb +361 -0
- data/lib/parse/live_query/circuit_breaker.rb +256 -0
- data/lib/parse/live_query/client.rb +1001 -0
- data/lib/parse/live_query/configuration.rb +224 -0
- data/lib/parse/live_query/event.rb +115 -0
- data/lib/parse/live_query/event_queue.rb +272 -0
- data/lib/parse/live_query/health_monitor.rb +214 -0
- data/lib/parse/live_query/logging.rb +149 -0
- data/lib/parse/live_query/subscription.rb +294 -0
- data/lib/parse/live_query.rb +163 -0
- data/lib/parse/lookup_rewriter.rb +445 -0
- data/lib/parse/model/acl.rb +968 -0
- data/lib/parse/model/associations/belongs_to.rb +275 -0
- data/lib/parse/model/associations/collection_proxy.rb +435 -0
- data/lib/parse/model/associations/has_many.rb +597 -0
- data/lib/parse/model/associations/has_one.rb +158 -0
- data/lib/parse/model/associations/pointer_collection_proxy.rb +134 -0
- data/lib/parse/model/associations/relation_collection_proxy.rb +177 -0
- data/lib/parse/model/bytes.rb +62 -0
- data/lib/parse/model/classes/audience.rb +262 -0
- data/lib/parse/model/classes/installation.rb +363 -0
- data/lib/parse/model/classes/job_schedule.rb +153 -0
- data/lib/parse/model/classes/job_status.rb +264 -0
- data/lib/parse/model/classes/product.rb +75 -0
- data/lib/parse/model/classes/push_status.rb +263 -0
- data/lib/parse/model/classes/role.rb +751 -0
- data/lib/parse/model/classes/session.rb +201 -0
- data/lib/parse/model/classes/user.rb +943 -0
- data/lib/parse/model/clp.rb +544 -0
- data/lib/parse/model/core/actions.rb +1268 -0
- data/lib/parse/model/core/builder.rb +139 -0
- data/lib/parse/model/core/create_lock.rb +386 -0
- data/lib/parse/model/core/describe.rb +382 -0
- data/lib/parse/model/core/enhanced_change_tracking.rb +159 -0
- data/lib/parse/model/core/errors.rb +38 -0
- data/lib/parse/model/core/fetching.rb +566 -0
- data/lib/parse/model/core/field_guards.rb +220 -0
- data/lib/parse/model/core/indexing.rb +382 -0
- data/lib/parse/model/core/parse_reference.rb +407 -0
- data/lib/parse/model/core/properties.rb +809 -0
- data/lib/parse/model/core/querying.rb +491 -0
- data/lib/parse/model/core/schema.rb +202 -0
- data/lib/parse/model/core/search_indexing.rb +174 -0
- data/lib/parse/model/date.rb +88 -0
- data/lib/parse/model/email.rb +213 -0
- data/lib/parse/model/file.rb +527 -0
- data/lib/parse/model/geojson.rb +271 -0
- data/lib/parse/model/geopoint.rb +261 -0
- data/lib/parse/model/model.rb +260 -0
- data/lib/parse/model/object.rb +2068 -0
- data/lib/parse/model/phone.rb +520 -0
- data/lib/parse/model/pointer.rb +443 -0
- data/lib/parse/model/polygon.rb +406 -0
- data/lib/parse/model/push.rb +975 -0
- data/lib/parse/model/shortnames.rb +8 -0
- data/lib/parse/model/time_zone.rb +141 -0
- data/lib/parse/model/validations/uniqueness_validator.rb +97 -0
- data/lib/parse/model/validations.rb +96 -0
- data/lib/parse/mongodb.rb +2300 -0
- data/lib/parse/pipeline_security.rb +554 -0
- data/lib/parse/query/constraint.rb +198 -0
- data/lib/parse/query/constraints.rb +3279 -0
- data/lib/parse/query/cursor.rb +434 -0
- data/lib/parse/query/n_plus_one_detector.rb +445 -0
- data/lib/parse/query/operation.rb +104 -0
- data/lib/parse/query/ordering.rb +66 -0
- data/lib/parse/query.rb +7028 -0
- data/lib/parse/schema/index_migrator.rb +291 -0
- data/lib/parse/schema/search_index_migrator.rb +289 -0
- data/lib/parse/schema.rb +494 -0
- data/lib/parse/stack/generators/rails.rb +40 -0
- data/lib/parse/stack/generators/templates/model.erb +51 -0
- data/lib/parse/stack/generators/templates/model_installation.rb +4 -0
- data/lib/parse/stack/generators/templates/model_role.rb +4 -0
- data/lib/parse/stack/generators/templates/model_session.rb +4 -0
- data/lib/parse/stack/generators/templates/model_user.rb +11 -0
- data/lib/parse/stack/generators/templates/parse.rb +12 -0
- data/lib/parse/stack/generators/templates/webhooks.rb +10 -0
- data/lib/parse/stack/railtie.rb +18 -0
- data/lib/parse/stack/tasks.rb +563 -0
- data/lib/parse/stack/version.rb +11 -0
- data/lib/parse/stack.rb +455 -0
- data/lib/parse/two_factor_auth/user_extension.rb +449 -0
- data/lib/parse/two_factor_auth.rb +310 -0
- data/lib/parse/webhooks/payload.rb +360 -0
- data/lib/parse/webhooks/registration.rb +199 -0
- data/lib/parse/webhooks/replay_protection.rb +189 -0
- data/lib/parse/webhooks.rb +510 -0
- data/lib/parse-stack-next.rb +5 -0
- data/lib/parse-stack.rb +5 -0
- data/parse-stack-next.gemspec +82 -0
- data/parse-stack.png +0 -0
- data/scripts/debug-ips.js +35 -0
- data/scripts/docker/Dockerfile.parse +13 -0
- data/scripts/docker/atlas-init.js +284 -0
- data/scripts/docker/docker-compose.atlas.yml +76 -0
- data/scripts/docker/docker-compose.test.yml +106 -0
- data/scripts/docker/mongo-init.js +21 -0
- data/scripts/eval_mcp_with_lm_studio.rb +274 -0
- data/scripts/start-parse.sh +90 -0
- data/scripts/start_mcp_server.rb +78 -0
- data/scripts/test_server_connection.rb +82 -0
- metadata +377 -0
data/bin/parse-console
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'optparse'
|
|
4
|
+
require 'json'
|
|
5
|
+
require 'open-uri'
|
|
6
|
+
require 'active_support'
|
|
7
|
+
require 'active_support/core_ext'
|
|
8
|
+
|
|
9
|
+
DEFAULT_CONFIG_FILE = 'config.json'
|
|
10
|
+
DEFAULT_CONFIG_CONTENTS = {
|
|
11
|
+
"apps": [{
|
|
12
|
+
"serverURL": "http://localhost:1337/parse",
|
|
13
|
+
"appId": "myAppId",
|
|
14
|
+
"masterKey": "myMasterKey",
|
|
15
|
+
"restAPIKey": "myRestAPIKey",
|
|
16
|
+
"javascriptKey": "myJavascriptKey",
|
|
17
|
+
"appName": "Parse Server App"
|
|
18
|
+
}]
|
|
19
|
+
}.freeze
|
|
20
|
+
|
|
21
|
+
opts = { verbose: false, pry: false }
|
|
22
|
+
opt_parser = OptionParser.new do |o|
|
|
23
|
+
|
|
24
|
+
o.banner = "Usage: #{File.basename($0)} [options] SERVER_URL"
|
|
25
|
+
o.separator ""
|
|
26
|
+
o.separator "Example:"
|
|
27
|
+
o.separator "#{File.basename($0)} -a APP_ID -m MASTER_KEY https://your-parse-server-url"
|
|
28
|
+
o.separator "#{File.basename($0)} -c ./config.json"
|
|
29
|
+
o.separator ""
|
|
30
|
+
o.separator "If you use the -m option, parse-console will automatically"
|
|
31
|
+
o.separator "import your schema as ruby models."
|
|
32
|
+
o.separator ""
|
|
33
|
+
o.separator "Options"
|
|
34
|
+
o.on('-a APP_ID', '--appId APP_ID', 'Parse App ID (required)') { |a| opts[:app_id] = a }
|
|
35
|
+
o.on('-k REST_API_KEY', '--restAPIKey REST_API_KEY', 'Parse REST API Key') { |a| opts[:api_key] = a }
|
|
36
|
+
o.on('-m MASTER_KEY', '--masterKey MASTER_KEY', 'Parse Master Key') { |a| opts[:master_key] = a }
|
|
37
|
+
o.on('-s SERVER_URL', '--serverURL SERVER_URL', 'The Parse server url.', 'Defaults to http://localhost:1337/parse') { |a| opts[:server_url] = a }
|
|
38
|
+
o.on('-v','--[no-]verbose', 'Run verbosely') { |v| opts[:verbose] ||= v }
|
|
39
|
+
o.on('--pry', 'Use Pry instead of IRB') { |v| opts[:pry] = v }
|
|
40
|
+
o.on('--version', 'Parse Stack version') do |v|
|
|
41
|
+
require 'parse/stack/version'
|
|
42
|
+
puts "Parse Stack : #{Parse::Stack::VERSION}"
|
|
43
|
+
exit 1
|
|
44
|
+
end
|
|
45
|
+
o.on('--config-sample', "Create a sample config file to use. See --config.") do
|
|
46
|
+
contents = JSON.pretty_generate(DEFAULT_CONFIG_CONTENTS)
|
|
47
|
+
File.open(DEFAULT_CONFIG_FILE, 'w') { |f| f.write(contents) }
|
|
48
|
+
puts "Created #{DEFAULT_CONFIG_FILE} : \n"
|
|
49
|
+
puts contents
|
|
50
|
+
puts "Edit #{DEFAULT_CONFIG_FILE} with your information and run: \n"
|
|
51
|
+
puts "\n\tparse-console -c ./#{DEFAULT_CONFIG_FILE}\n\n"
|
|
52
|
+
exit 1
|
|
53
|
+
end
|
|
54
|
+
o.on('-c','--config CONFIG_JSON', "Load config from a parse-dashboard.json compatible file.") do |filepath|
|
|
55
|
+
unless File.exist?(filepath)
|
|
56
|
+
$stderr.puts "File #{filepath} does not exist."
|
|
57
|
+
exit 1
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
begin
|
|
61
|
+
puts "Loading config: #{filepath}"
|
|
62
|
+
file = File.read(filepath)
|
|
63
|
+
config = JSON.parse file
|
|
64
|
+
app = config["apps"].is_a?(Array) ? config["apps"].first : config["apps"]
|
|
65
|
+
app = config if app.nil? # uses parse-server config.json
|
|
66
|
+
opts[:server_url] ||= app["serverURL"]
|
|
67
|
+
opts[:app_id] ||= app["appId"]
|
|
68
|
+
opts[:api_key] ||= app["restAPIKey"]
|
|
69
|
+
opts[:master_key] ||= app["masterKey"]
|
|
70
|
+
rescue Exception => e
|
|
71
|
+
$stderr.puts "Error: Incompatible JSON format for #{filepath} (#{e})"
|
|
72
|
+
exit 1
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
o.on('--url URL', 'Load the env config from a url.') do |url|
|
|
77
|
+
begin
|
|
78
|
+
puts "Loading config: #{url}"
|
|
79
|
+
json = JSON.load open(url)
|
|
80
|
+
raise "Contents not a JSON hash." unless json.is_a?(Hash)
|
|
81
|
+
json.each { |k,v| ENV[k.upcase] = v }
|
|
82
|
+
opts[:server_url] ||= ENV['PARSE_SERVER_URL']
|
|
83
|
+
opts[:app_id] ||= ENV['PARSE_SERVER_APPLICATION_ID'] || ENV['PARSE_APP_ID']
|
|
84
|
+
opts[:api_key] ||= ENV['PARSE_SERVER_REST_API_KEY'] || ENV['PARSE_API_KEY']
|
|
85
|
+
opts[:master_key] ||= ENV['PARSE_SERVER_MASTER_KEY'] || ENV['PARSE_MASTER_KEY']
|
|
86
|
+
rescue Exception => e
|
|
87
|
+
$stderr.puts "Error: Invalid JSON format for #{url} (#{e})"
|
|
88
|
+
exit 1
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
opt_parser.parse!
|
|
93
|
+
|
|
94
|
+
opts[:server_url] ||= ARGV.shift || 'http://localhost:1337/parse'
|
|
95
|
+
|
|
96
|
+
if opts[:app_id].nil?
|
|
97
|
+
$stderr.puts "Error: Option --app_id missing\n"
|
|
98
|
+
$stderr.puts opt_parser
|
|
99
|
+
exit 1
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
if opts[:api_key].nil? && opts[:master_key].nil?
|
|
103
|
+
$stderr.puts "Error: You must supply either --api_key (REST API Key) or --master_key (Parse Master key).\n"
|
|
104
|
+
$stderr.puts opt_parser
|
|
105
|
+
exit 1
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# lazy loading
|
|
109
|
+
require "parse/stack"
|
|
110
|
+
Parse.setup server_url: opts[:server_url],
|
|
111
|
+
app_id: opts[:app_id],
|
|
112
|
+
api_key: opts[:api_key],
|
|
113
|
+
master_key: opts[:master_key]
|
|
114
|
+
Parse.logging = true if opts[:verbose]
|
|
115
|
+
puts "Server : #{Parse.client.server_url}"
|
|
116
|
+
puts "App Id : #{Parse.client.app_id}"
|
|
117
|
+
puts "Master : #{Parse.client.master_key.present?}"
|
|
118
|
+
|
|
119
|
+
if Parse.client.master_key.present?
|
|
120
|
+
puts "Schema : imported"
|
|
121
|
+
Parse.auto_generate_models!.each do |model|
|
|
122
|
+
puts "Generated #{model}" if opts[:verbose]
|
|
123
|
+
end
|
|
124
|
+
else
|
|
125
|
+
puts "Schema : skipped (requires master key)"
|
|
126
|
+
end
|
|
127
|
+
# Create shortnames
|
|
128
|
+
Parse.use_shortnames!
|
|
129
|
+
|
|
130
|
+
if opts[:pry]
|
|
131
|
+
require "pry"
|
|
132
|
+
Pry.start
|
|
133
|
+
else
|
|
134
|
+
require "irb"
|
|
135
|
+
IRB.start
|
|
136
|
+
end
|
data/bin/server
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "parse/stack"
|
|
5
|
+
|
|
6
|
+
require "rack"
|
|
7
|
+
require "puma"
|
|
8
|
+
|
|
9
|
+
# For Rack v3 compatibility, Rack::Server has been moved to rackup gem
|
|
10
|
+
# Using a simple Puma server directly instead
|
|
11
|
+
puts "Starting Parse::Webhooks server on port 9292..."
|
|
12
|
+
puts "Visit http://localhost:9292"
|
|
13
|
+
|
|
14
|
+
app = Parse::Webhooks
|
|
15
|
+
server = Puma::Server.new(app)
|
|
16
|
+
server.add_tcp_listener "0.0.0.0", 9292
|
|
17
|
+
server.run
|
data/bin/setup
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"appId": "myAppId",
|
|
3
|
+
"masterKey": "myMasterKey",
|
|
4
|
+
"restAPIKey": "test-rest-key",
|
|
5
|
+
"databaseURI": "mongodb://admin:password@mongo:27017/parse?authSource=admin",
|
|
6
|
+
"serverURL": "http://localhost:1337/parse",
|
|
7
|
+
"mountPath": "/parse",
|
|
8
|
+
"cloud": "/parse-server/cloud/main.js",
|
|
9
|
+
"logLevel": "info",
|
|
10
|
+
"allowClientClassCreation": true,
|
|
11
|
+
"allowCustomObjectId": true
|
|
12
|
+
}
|
data/docs/TEST_SERVER.md
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# Parse Stack Test Server Setup
|
|
2
|
+
|
|
3
|
+
This document explains how to set up a local Parse Server for testing the parse-stack Ruby SDK.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### Option 1: Using Make (Recommended)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Start the test server
|
|
11
|
+
make test-server-start
|
|
12
|
+
|
|
13
|
+
# Test the connection
|
|
14
|
+
make test-connection
|
|
15
|
+
|
|
16
|
+
# Run integration tests
|
|
17
|
+
make test-integration
|
|
18
|
+
|
|
19
|
+
# Stop the test server
|
|
20
|
+
make test-server-stop
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Option 2: Docker Compose
|
|
24
|
+
|
|
25
|
+
1. **Start the test server:**
|
|
26
|
+
```bash
|
|
27
|
+
docker-compose -f docker-compose.test.yml up -d
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
2. **Test the connection:**
|
|
31
|
+
```bash
|
|
32
|
+
ruby test_server_connection.rb
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
3. **Run integration tests:**
|
|
36
|
+
```bash
|
|
37
|
+
PARSE_TEST_USE_DOCKER=true bundle exec rake test
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
4. **Stop the test server:**
|
|
41
|
+
```bash
|
|
42
|
+
docker-compose -f docker-compose.test.yml down
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Option 3: Use Your Own Parse Server
|
|
46
|
+
|
|
47
|
+
Set environment variables to point to your Parse Server:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
export PARSE_TEST_SERVER_URL="http://your-server:1337/parse"
|
|
51
|
+
export PARSE_TEST_APP_ID="your-app-id"
|
|
52
|
+
export PARSE_TEST_API_KEY="your-rest-key"
|
|
53
|
+
export PARSE_TEST_MASTER_KEY="your-master-key"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Services Included
|
|
57
|
+
|
|
58
|
+
The Docker Compose setup provides:
|
|
59
|
+
|
|
60
|
+
- **MongoDB** (port 27017): Database backend
|
|
61
|
+
- **Parse Server** (port 1337): Main API server with custom startup script
|
|
62
|
+
- **Parse Dashboard** (port 4040): Web interface for data management
|
|
63
|
+
|
|
64
|
+
## Technical Implementation
|
|
65
|
+
|
|
66
|
+
### Custom Parse Server Image
|
|
67
|
+
|
|
68
|
+
The setup uses a custom Docker image built on top of `parseplatform/parse-server:8.2.3` that includes:
|
|
69
|
+
|
|
70
|
+
- **Custom startup script** (`scripts/start-parse.sh`) that sets the `PARSE_SERVER_MASTER_KEY_IPS` environment variable
|
|
71
|
+
- **IP restriction bypass** allowing requests from any IP address (`0.0.0.0/0,::/0`)
|
|
72
|
+
- **Automatic environment variable setup** for proper master key authentication
|
|
73
|
+
|
|
74
|
+
### Master Key Authentication
|
|
75
|
+
|
|
76
|
+
The setup resolves Parse Server's IP restriction for master key usage by:
|
|
77
|
+
|
|
78
|
+
1. Using a custom Docker image with an embedded startup script
|
|
79
|
+
2. Setting `PARSE_SERVER_MASTER_KEY_IPS=0.0.0.0/0,::/0` to allow all IP addresses
|
|
80
|
+
3. This enables schema operations and full master key functionality for testing
|
|
81
|
+
|
|
82
|
+
### File Structure
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
parse-stack-next/
|
|
86
|
+
├── scripts/
|
|
87
|
+
│ ├── docker/
|
|
88
|
+
│ │ ├── docker-compose.test.yml # Main Docker Compose configuration
|
|
89
|
+
│ │ └── Dockerfile.parse # Custom Parse Server image
|
|
90
|
+
│ ├── start-parse.sh # Startup script with environment setup
|
|
91
|
+
│ └── test_server_connection.rb # Connection test script
|
|
92
|
+
├── config/
|
|
93
|
+
│ └── parse-config.json # Parse Server configuration (unused)
|
|
94
|
+
├── test/
|
|
95
|
+
│ ├── cloud/
|
|
96
|
+
│ │ └── main.js # Cloud Code for testing
|
|
97
|
+
│ └── support/
|
|
98
|
+
│ ├── test_server.rb # Ruby test helper utilities
|
|
99
|
+
│ └── docker_helper.rb # Docker container management
|
|
100
|
+
└── .env.test # Environment variable defaults
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Test Configuration
|
|
104
|
+
|
|
105
|
+
### Environment Variables
|
|
106
|
+
|
|
107
|
+
| Variable | Default | Description |
|
|
108
|
+
|----------|---------|-------------|
|
|
109
|
+
| `PARSE_TEST_SERVER_URL` | `http://localhost:1337/parse` | Parse Server URL |
|
|
110
|
+
| `PARSE_TEST_APP_ID` | `myAppId` | Application ID |
|
|
111
|
+
| `PARSE_TEST_API_KEY` | `test-rest-key` | REST API Key |
|
|
112
|
+
| `PARSE_TEST_MASTER_KEY` | `myMasterKey` | Master Key |
|
|
113
|
+
| `PARSE_TEST_USE_DOCKER` | `false` | Auto-manage Docker containers |
|
|
114
|
+
| `PARSE_TEST_AUTO_START` | `false` | Start containers automatically |
|
|
115
|
+
| `PARSE_TEST_AUTO_STOP` | `false` | Stop containers on exit |
|
|
116
|
+
|
|
117
|
+
### Using `.env.test`
|
|
118
|
+
|
|
119
|
+
Copy and customize the test environment file:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
cp .env.test .env.test.local
|
|
123
|
+
# Edit .env.test.local with your settings
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Writing Integration Tests
|
|
127
|
+
|
|
128
|
+
### Basic Setup
|
|
129
|
+
|
|
130
|
+
```ruby
|
|
131
|
+
require_relative 'test_helper_integration'
|
|
132
|
+
|
|
133
|
+
class MyIntegrationTest < Minitest::Test
|
|
134
|
+
include ParseStackIntegrationTest
|
|
135
|
+
|
|
136
|
+
def test_user_creation
|
|
137
|
+
with_parse_server do
|
|
138
|
+
user = create_test_user(username: 'testuser')
|
|
139
|
+
assert user.id.present?
|
|
140
|
+
assert_equal 'testuser', user.username
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Test Helpers Available
|
|
147
|
+
|
|
148
|
+
- `with_parse_server { }` - Skip test if server unavailable
|
|
149
|
+
- `create_test_user(attributes)` - Create and track test user
|
|
150
|
+
- `create_test_object(class_name, attributes)` - Create and track test object
|
|
151
|
+
- `reset_database!` - Clear all non-system data
|
|
152
|
+
- `@test_context.track(object)` - Track object for cleanup
|
|
153
|
+
|
|
154
|
+
### Manual Server Management
|
|
155
|
+
|
|
156
|
+
```ruby
|
|
157
|
+
# In your tests or console
|
|
158
|
+
require 'test/support/docker_helper'
|
|
159
|
+
|
|
160
|
+
# Start containers
|
|
161
|
+
Parse::Test::DockerHelper.start!
|
|
162
|
+
|
|
163
|
+
# Check if running
|
|
164
|
+
Parse::Test::DockerHelper.running?
|
|
165
|
+
|
|
166
|
+
# View logs
|
|
167
|
+
puts Parse::Test::DockerHelper.logs
|
|
168
|
+
|
|
169
|
+
# Stop containers
|
|
170
|
+
Parse::Test::DockerHelper.stop!
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Dashboard Access
|
|
174
|
+
|
|
175
|
+
When using Docker Compose, you can access the Parse Dashboard at:
|
|
176
|
+
- URL: http://localhost:4040
|
|
177
|
+
- Username: `admin`
|
|
178
|
+
- Password: `admin`
|
|
179
|
+
|
|
180
|
+
## Cloud Code Testing
|
|
181
|
+
|
|
182
|
+
Sample cloud functions are provided in `test/cloud/main.js`:
|
|
183
|
+
|
|
184
|
+
```ruby
|
|
185
|
+
# Test cloud functions
|
|
186
|
+
result = Parse::CloudFunction.call('hello', name: 'World')
|
|
187
|
+
assert_equal 'Hello World!', result
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Troubleshooting
|
|
191
|
+
|
|
192
|
+
### Docker Issues
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Check container status
|
|
196
|
+
docker-compose -f docker-compose.test.yml ps
|
|
197
|
+
|
|
198
|
+
# View Parse Server logs
|
|
199
|
+
docker logs parse-stack-test-server
|
|
200
|
+
|
|
201
|
+
# Reset everything
|
|
202
|
+
docker-compose -f docker-compose.test.yml down -v
|
|
203
|
+
docker-compose -f docker-compose.test.yml up -d
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Master Key Authentication Issues
|
|
207
|
+
|
|
208
|
+
If you see `Request using master key rejected as the request IP address ... is not set in Parse Server option 'masterKeyIps'`:
|
|
209
|
+
|
|
210
|
+
1. **Verify the custom image is built**:
|
|
211
|
+
```bash
|
|
212
|
+
docker-compose -f docker-compose.test.yml build parse
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
2. **Check startup script execution**:
|
|
216
|
+
```bash
|
|
217
|
+
docker logs parse-stack-test-server | grep "PARSE_SERVER_MASTER_KEY_IPS"
|
|
218
|
+
```
|
|
219
|
+
Should show: `PARSE_SERVER_MASTER_KEY_IPS: 0.0.0.0/0,::/0`
|
|
220
|
+
|
|
221
|
+
3. **Test master key directly**:
|
|
222
|
+
```bash
|
|
223
|
+
curl -X GET \
|
|
224
|
+
-H "X-Parse-Application-Id: myAppId" \
|
|
225
|
+
-H "X-Parse-Master-Key: myMasterKey" \
|
|
226
|
+
http://localhost:1337/parse/schemas
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Connection Issues
|
|
230
|
+
|
|
231
|
+
```ruby
|
|
232
|
+
# Test connectivity in console
|
|
233
|
+
require 'test/support/test_server'
|
|
234
|
+
Parse::Test::ServerHelper.setup
|
|
235
|
+
Parse::Test::ServerHelper.server_available?
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Port Conflicts
|
|
239
|
+
|
|
240
|
+
If ports 1337, 4040, or 27017 are in use, modify `docker-compose.test.yml`:
|
|
241
|
+
|
|
242
|
+
```yaml
|
|
243
|
+
services:
|
|
244
|
+
parse:
|
|
245
|
+
ports:
|
|
246
|
+
- "1338:1337" # Use port 1338 instead
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Then update your environment variables accordingly.
|
|
250
|
+
|
|
251
|
+
## Production vs Test Differences
|
|
252
|
+
|
|
253
|
+
The test server configuration includes:
|
|
254
|
+
- Relaxed security settings for testing
|
|
255
|
+
- Auto-creation of classes
|
|
256
|
+
- Verbose logging
|
|
257
|
+
- Sample cloud code
|
|
258
|
+
|
|
259
|
+
**Never use these settings in production!**
|
|
260
|
+
|
|
261
|
+
## Status
|
|
262
|
+
|
|
263
|
+
✅ **Working Setup**: This test server configuration has been verified to work with:
|
|
264
|
+
- Parse Server 8.2.3
|
|
265
|
+
- MongoDB 5.0
|
|
266
|
+
- Master key authentication for schema operations
|
|
267
|
+
- Basic CRUD operations via REST API
|
|
268
|
+
- Ruby Parse Stack SDK connection
|
|
269
|
+
- Cloud Code execution
|
|
270
|
+
|
|
271
|
+
The setup successfully resolves Parse Server's IP restriction issues that typically prevent master key usage in Docker environments.
|
data/docs/_config.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
theme: jekyll-theme-midnight
|