Переглянути джерело

Merge pull request #92 from run-project/feature/test-screen

Add a page to assist users to test the parse server
Héctor Ramos 9 роки тому
батько
коміт
62c82829ae
7 змінених файлів з 504 додано та 3 видалено
  1. 2 1
      README.md
  2. 8 0
      index.js
  3. 2 2
      package.json
  4. 238 0
      public/assets/css/style.css
  5. BIN
      public/assets/images/parse-logo.png
  6. 153 0
      public/assets/js/script.js
  7. 101 0
      public/test.html

+ 2 - 1
README.md

@@ -87,7 +87,8 @@ A detailed tutorial is available here:
 
 
 # Using it
 # Using it
 
 
-You can use the REST API, the JavaScript SDK, and any of our open-source SDKs:
+Before using it, you can access a test page to verify if the basic setup is working fine [http://localhost:1337/test](http://localhost:1337/test).
+Then you can use the REST API, the JavaScript SDK, and any of our open-source SDKs:
 
 
 Example request to a server running locally:
 Example request to a server running locally:
 
 

+ 8 - 0
index.js

@@ -3,6 +3,7 @@
 
 
 var express = require('express');
 var express = require('express');
 var ParseServer = require('parse-server').ParseServer;
 var ParseServer = require('parse-server').ParseServer;
+var path = require('path');
 
 
 var databaseUri = process.env.DATABASE_URI || process.env.MONGOLAB_URI;
 var databaseUri = process.env.DATABASE_URI || process.env.MONGOLAB_URI;
 
 
@@ -23,6 +24,9 @@ var api = new ParseServer({
 
 
 var app = express();
 var app = express();
 
 
+// Config static middleware for assets
+app.use('/static', express.static(path.join(__dirname, '/public')));
+
 // Serve the Parse API on the /parse URL prefix
 // Serve the Parse API on the /parse URL prefix
 var mountPath = process.env.PARSE_MOUNT || '/parse';
 var mountPath = process.env.PARSE_MOUNT || '/parse';
 app.use(mountPath, api);
 app.use(mountPath, api);
@@ -32,6 +36,10 @@ app.get('/', function(req, res) {
   res.status(200).send('I dream of being a web site.');
   res.status(200).send('I dream of being a web site.');
 });
 });
 
 
+app.get('/test', function(req, res) {
+  res.sendFile(path.join(__dirname, '/public/test.html'));
+});
+
 var port = process.env.PORT || 1337;
 var port = process.env.PORT || 1337;
 app.listen(port, function() {
 app.listen(port, function() {
     console.log('parse-server-example running on port ' + port + '.');
     console.log('parse-server-example running on port ' + port + '.');

+ 2 - 2
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "parse-server-example",
   "name": "parse-server-example",
-  "version": "1.2.0",
+  "version": "1.3.0",
   "description": "An example Parse API server using the parse-server module",
   "description": "An example Parse API server using the parse-server module",
   "main": "index.js",
   "main": "index.js",
   "repository": {
   "repository": {
@@ -9,7 +9,7 @@
   },
   },
   "license": "MIT",
   "license": "MIT",
   "dependencies": {
   "dependencies": {
-    "express": "~4.2.x",
+    "express": "~4.11.x",
     "kerberos": "~0.0.x",
     "kerberos": "~0.0.x",
     "parse": "~1.6.12",
     "parse": "~1.6.12",
     "parse-server": "~2.1.4"
     "parse-server": "~2.1.4"

+ 238 - 0
public/assets/css/style.css

@@ -0,0 +1,238 @@
+body {
+  margin: 0;
+  padding: 0;
+  font-family: Helvetica, Arial, sans-serif;
+  font-size: 14px;
+  letter-spacing: 0.2px;
+  line-height: 24px;
+  color: #585858;
+}
+
+a {
+  color: #169CEE;
+  text-decoration: underline;
+}
+
+a:hover {
+  color: #2C3D50;
+}
+
+a:visited {
+  color: #2a6496;
+}
+
+
+/*
+  helpers
+ */
+
+.align-center {
+  text-align: center;
+}
+
+.hidden {
+  display: none;
+}
+
+/*
+  app css
+ */
+
+.container {
+  margin: 0 auto;
+  margin-top: 45px;
+  max-width: 860px;
+}
+
+#parse-logo {
+  width: 109px;
+  height: 110px;
+  margin: 0 0 20px;
+  text-align: center;
+}
+
+.up-and-running, .time-to-deploy {
+  font-weight: bold;
+}
+
+.advice {
+  margin-bottom: 40px;
+}
+
+.advice {
+  background: #f4f4f4;
+  border-radius: 4px;
+  -webkit-border-radius: 4px 4px;
+  -moz-border-radius: 4px 4px;
+  -ms-border-radius: 4px 4px;
+  -o-border-radius: 4px 4px;
+  padding: 10px 20px;
+}
+
+#parse-url {
+  color: #169CEE;
+  font-weight: bold;
+}
+
+.step--container {
+  margin: 30px 0 20px;
+  border-top: 1px solid #E2E2E2;
+  padding-top: 30px;
+}
+
+/* Disabled step */
+.step--disabled .step--number {
+  background: #fff;
+  border-color: #B5B5B5;
+  color: #B5B5B5;
+}
+
+.step--disabled .step--info {
+  border-color: #B5B5B5;
+  color: #B5B5B5;
+}
+
+.step--disabled .step--action-btn,
+  .step--disabled .step--action-btn:hover {
+  border-color: #B5B5B5;
+  background: #fff;
+  color: #B5B5B5;
+  cursor: default;
+}
+
+/* Disabled step eof */
+
+.step--action-btn.success,
+.step--action-btn.success:hover {
+  background: #57C689;
+  border-color: #57C689;
+  color: #fff;
+  cursor: default;
+  font-weight: bold;
+}
+
+.step--number {
+  background: #169CEE;
+  border: 1px solid #169CEE;
+  border-radius: 28px;
+  -webkit-border-radius: 28px 28px;
+  -moz-border-radius: 28px 28px;
+  -ms-border-radius: 28px 28px;
+  -o-border-radius: 28px 28px;
+  display: block;
+  margin: auto;
+  width: 47px;
+  height: 47px;
+  font-weight: bolder;
+  font-size: 20px;
+  color: #FFFFFF;
+  line-height: 47px; /* follows width and height */
+}
+
+.step--info { }
+
+.step--action-btn {
+  color: #169CEE;
+  font-size: 14px;
+  font-weight: 100;
+  border: 1px solid #169CEE;
+  padding: 12px 18px;
+  border-radius: 28px;
+  -webkit-border-radius: 28px 28px;
+  -moz-border-radius: 28px 28px;
+  -ms-border-radius: 28px 28px;
+  -o-border-radius: 28px 28px;
+  cursor: pointer;
+  text-decoration: none;
+  display:inline-block;
+  text-align: center;
+  text-transform: uppercase;
+}
+
+.step--action-btn:hover {
+  background: #169CEE;
+  color: white;
+}
+
+.step--pre {
+  margin-top: 4px;
+  margin-bottom: 0;
+  background: #f4f4f4;
+  border-radius: 4px;
+  -webkit-border-radius: 4px 4px;
+  -moz-border-radius: 4px 4px;
+  -ms-border-radius: 4px 4px;
+  -o-border-radius: 4px 4px;
+  padding: 10px 20px;
+  word-wrap: break-word;
+  white-space: inherit;
+  font-size: 13px;
+}
+
+#local-parse-working {
+  font-size: 18px;
+  line-height: 24px;
+  color: #57C689;
+  font-weight: bold;
+}
+
+#step-4 .step--number {
+  background: #57C689;
+  border-color: #57C689;
+  color: #fff;
+  display: inline-block;
+}
+
+.step--deploy-btn {
+  display: block;
+  margin-top: 20px;
+  width: 170px;
+  color: #57C689 !important;
+  font-weight: bold;
+  border-color: #57C689;
+}
+
+.step--deploy-btn:hover {
+  background: #57C689;
+  color: #fff !important;
+}
+
+#prod-test {
+  margin-bottom: 60px;
+}
+
+#prod-test input {
+  background-color: #fff;
+  border: 1px solid #B5B5B5;
+  color: #000000;
+  font-family: "Inconsolata";
+  font-size: 16px;
+  line-height: 17px;
+  padding: 12px;
+  width: 260px;
+  border-radius: 4px;
+  -webkit-border-radius: 4px 4px;
+  -moz-border-radius: 4px 4px;
+  -ms-border-radius: 4px 4px;
+  -o-border-radius: 4px 4px;
+  display:block;
+  margin-bottom: 10px;
+}
+
+#footer {
+  border-top: 1px solid #E2E2E2;
+  padding: 20px;
+}
+
+#footer ul li {
+  list-style-type: none;
+  display:inline-block;
+}
+#footer ul li:after {
+  content: "-";
+  padding: 10px;
+}
+#footer ul li:last-child:after {
+  content: "";
+}
+

BIN
public/assets/images/parse-logo.png


+ 153 - 0
public/assets/js/script.js

@@ -0,0 +1,153 @@
+/**
+ *  Steps handler
+ */
+
+var Steps = {}
+
+Steps.init = function() {
+  this.buildParseUrl();
+  this.bindBtn('#step-1-btn', function(e){
+    ParseRequest.postData();
+    e.preventDefault();
+  })
+}
+
+Steps.buildParseUrl = function() {
+  var url = Config.getUrl();
+  $('#parse-url').html(url + '/parse');
+}
+
+Steps.bindBtn = function(id, callback) {
+  $(id).click(callback)
+}
+
+Steps.closeStep = function(id) {
+  $(id).addClass('step--disabled');
+}
+
+Steps.openStep  = function(id) {
+  $(id).removeClass('step--disabled');
+}
+
+Steps.fillStepOutput  = function(id, data) {
+  $(id).html('Output: ' + data).slideDown();
+}
+
+Steps.fillBtn  = function(id, message) {
+  $(id).addClass('success').html('✓  ' + message);
+}
+
+Steps.showWorkingMessage = function() {
+  $('#step-4').delay(500).slideDown();
+}
+
+
+/**
+ *  Parse requests handler
+ */
+
+var ParseRequest = {};
+
+ParseRequest.postData = function() {
+  XHR.setCallback(function(data){
+    // store objectID
+    Store.objectId = JSON.parse(data).objectId;
+    // close first step
+    Steps.closeStep('#step-1');
+    Steps.fillStepOutput('#step-1-output', data)
+    Steps.fillBtn('#step-1-btn', 'Posted');
+    // open second step
+    Steps.openStep('#step-2');
+    Steps.bindBtn('#step-2-btn', function(e){
+      ParseRequest.getData();
+      e.preventDefault();
+    });
+  });
+  XHR.POST('/parse/classes/GameScore');
+}
+
+ParseRequest.getData = function() {
+  XHR.setCallback(function(data){
+    // close second step
+    Steps.closeStep('#step-2');
+    Steps.fillStepOutput('#step-2-output', data)
+    Steps.fillBtn('#step-2-btn', 'Fetched');
+    // open third step
+    Steps.openStep('#step-3');
+    Steps.bindBtn('#step-3-btn', function(e){
+      ParseRequest.postCloudCodeData();
+      e.preventDefault();
+    })
+  });
+  XHR.GET('/parse/classes/GameScore');
+}
+
+ParseRequest.postCloudCodeData = function() {
+  XHR.setCallback(function(data){
+    // close second step
+    Steps.closeStep('#step-3');
+    Steps.fillStepOutput('#step-3-output', data)
+    Steps.fillBtn('#step-3-btn', 'Tested');
+    // open third step
+    Steps.showWorkingMessage();
+  });
+  XHR.POST('/parse/functions/hello');
+}
+
+
+/**
+ * Store objectId and other references
+ */
+
+var Store = {
+  objectId: ""
+};
+
+var Config = {}
+
+Config.getUrl = function() {
+  if (url) return url;
+  var port = window.location.port;
+  var url = window.location.protocol + '//' + window.location.hostname;
+  if (port) url = url + ':' + port;
+  return url;
+}
+
+
+/**
+ * XHR object
+ */
+
+var XHR = {}
+
+XHR.setCallback = function(callback) {
+  this.xhttp = new XMLHttpRequest();
+  var _self = this;
+  this.xhttp.onreadystatechange = function() {
+    if (_self.xhttp.readyState == 4 && _self.xhttp.status >= 200 && _self.xhttp.status <= 299) {
+      callback(_self.xhttp.responseText);
+    }
+  };
+}
+
+XHR.POST = function(path, callback) {
+  var seed = {"score":1337,"playerName":"Sean Plott","cheatMode":false}
+  this.xhttp.open("POST", Config.getUrl() + path, true);
+  this.xhttp.setRequestHeader("X-Parse-Application-Id", "myAppId");
+  this.xhttp.setRequestHeader("Content-type", "application/json");
+  this.xhttp.send(JSON.stringify(seed));
+}
+
+XHR.GET = function(path, callback) {
+  this.xhttp.open("GET", Config.getUrl() + path + '/' + Store.objectId, true);
+  this.xhttp.setRequestHeader("X-Parse-Application-Id", "myAppId");
+  this.xhttp.setRequestHeader("Content-type", "application/json");
+  this.xhttp.send(null);
+}
+
+
+/**
+ *  Boot
+ */
+
+Steps.init();

+ 101 - 0
public/test.html

@@ -0,0 +1,101 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <title>Parse Serve example</title>
+    <link href="https://cdnjs.cloudflare.com/ajax/libs/pure/0.6.0/grids-min.css" rel="stylesheet">
+    <link href="/static/assets/css/style.css" rel="stylesheet">
+  </head>
+
+  <body>
+    <div class="container">
+      <div class="align-center">
+        <img id="parse-logo" src="/static/assets/images/parse-logo.png">
+      </div>
+
+      <div class="advice">
+        <p><strong>Hi</strong>! We've prepared a small 3-steps page to assist you testing your local Parse server.</p>
+        <p>These first steps will help you run and test the Parse server locally and were referrenced by the <a href="https://github.com/ParsePlatform/parse-server/wiki/Migrating-an-Existing-Parse-App">migration guide</a> provided by <a href="https://github.com/ParsePlatform/">ParsePlataform</a>.</p>
+      </div>
+
+      <p class="up-and-running">Looks like our local Parse Serve is running under <span id="parse-url">...</span>. Let’s test it?
</p>
+
+      <p>We have an express server with Parse server running on top of it connected to a MongoDB.</p>
+
+      <p>The following steps will try to save some data on parse server and then fetch it back. Hey ho?</p>
+
+      <div id="step-1" class="pure-g step--container">
+        <div class="pure-u-1-5 align-center">
+          <span class="step--number">1</a>
+        </div>
+        <div class="pure-u-4-5">
+          <p class="step--info">Post data to local parse server:</p>
+          <div class="pure-g">
+            <div class="pure-u-1-5">
+              <a href="#" id="step-1-btn" class="step--action-btn">Post</a>
+            </div>
+            <div class="pure-u-4-5">
+              <!-- <div class="code-label " title="Output">Output</div> -->
+              <pre id="step-1-output" class="step--pre hidden">...</pre>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div id="step-2" class="pure-g step--container step--disabled">
+        <div class="pure-u-1-5  align-center">
+          <span class="step--number">2</a>
+        </div>
+        <div class="pure-u-4-5">
+          <p class="step--info">Fetch data from local parse server:</p>
+          <div class="pure-g">
+            <div class="pure-u-1-5">
+              <a href="#" id="step-2-btn" class="step--action-btn">Fetch</a>
+            </div>
+            <div class="pure-u-4-5">
+              <pre id="step-2-output" class="step--pre hidden">...</pre>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div id="step-3" class="pure-g step--container step--disabled">
+        <div class="pure-u-1-5  align-center">
+          <span class="step--number">3</a>
+        </div>
+        <div class="pure-u-4-5">
+          <p class="step--info">Test Cloud Code function from ./cloud/main.js:</p>
+          <div class="pure-g">
+            <div class="pure-u-1-5">
+              <a href="#" id="step-3-btn" class="step--action-btn">TEST</a>
+            </div>
+            <div class="pure-u-4-5">
+              <pre id="step-3-output" class="step--pre hidden">...</pre>
+            </div>
+          </div>
+        </div>
+      </div>
+
+       <div id="step-4" class="pure-g step--container hidden">
+        <div class="pure-u-1-5  align-center">
+          <span class="step--number">✓</a>
+        </div>
+        <div class="pure-u-4-5">
+          <p id="local-parse-working">
+          Congrats! Our local Parse server is working. :)
+          </p>
+        </div>
+      </div>
+
+      <footer id="footer" class="align-center">
+        <ul>
+          <li><a href="https://parse.com" target="_blank">Parse.com</a></li>
+          <li><a href="https://parse.com/docs" target="_blank">Docs</a></li>
+          <li><a href="https://github.com/ParsePlatform/parse-server-example" target="_blank">Github</a></li>
+        </ul>
+      </footer>
+
+    </div>
+    <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
+    <script src="/static/assets/js/script.js"></script>
+  </body>
+</html>