Merge branch 'master' into update-proxy-info
This commit is contained in:
@@ -3,9 +3,9 @@ const mimeToMode = {
|
||||
"text/html": "html",
|
||||
"application/xml": "xml",
|
||||
"application/hal+json": "json",
|
||||
"application/json": "json"
|
||||
"application/json": "json",
|
||||
}
|
||||
|
||||
export function getEditorLangForMimeType(mimeType) {
|
||||
return mimeToMode[mimeType] || "plain_text";
|
||||
return mimeToMode[mimeType] || "plain_text"
|
||||
}
|
||||
|
||||
140
functions/fb.js
140
functions/fb.js
@@ -1,6 +1,6 @@
|
||||
import firebase from "firebase/app";
|
||||
import "firebase/firestore";
|
||||
import "firebase/auth";
|
||||
import firebase from "firebase/app"
|
||||
import "firebase/firestore"
|
||||
import "firebase/auth"
|
||||
|
||||
// Initialize Firebase, copied from cloud console
|
||||
const firebaseConfig = {
|
||||
@@ -11,12 +11,12 @@ const firebaseConfig = {
|
||||
storageBucket: "postwoman-api.appspot.com",
|
||||
messagingSenderId: "421993993223",
|
||||
appId: "1:421993993223:web:ec0baa8ee8c02ffa1fc6a2",
|
||||
measurementId: "G-ERJ6025CEB"
|
||||
};
|
||||
firebase.initializeApp(firebaseConfig);
|
||||
measurementId: "G-ERJ6025CEB",
|
||||
}
|
||||
firebase.initializeApp(firebaseConfig)
|
||||
|
||||
// a reference to the users collection
|
||||
const usersCollection = firebase.firestore().collection("users");
|
||||
const usersCollection = firebase.firestore().collection("users")
|
||||
|
||||
// the shared state object that any vue component
|
||||
// can get access to
|
||||
@@ -34,13 +34,13 @@ export const fb = {
|
||||
author_name: fb.currentUser.displayName,
|
||||
author_image: fb.currentUser.photoURL,
|
||||
message,
|
||||
label
|
||||
};
|
||||
label,
|
||||
}
|
||||
usersCollection
|
||||
.doc(fb.currentUser.uid)
|
||||
.collection("feeds")
|
||||
.add(dt)
|
||||
.catch(e => console.error("error inserting", dt, e));
|
||||
.catch(e => console.error("error inserting", dt, e))
|
||||
},
|
||||
deleteFeed: id => {
|
||||
usersCollection
|
||||
@@ -48,7 +48,7 @@ export const fb = {
|
||||
.collection("feeds")
|
||||
.doc(id)
|
||||
.delete()
|
||||
.catch(e => console.error("error deleting", id, e));
|
||||
.catch(e => console.error("error deleting", id, e))
|
||||
},
|
||||
writeSettings: async (setting, value) => {
|
||||
const st = {
|
||||
@@ -57,22 +57,22 @@ export const fb = {
|
||||
author_name: fb.currentUser.displayName,
|
||||
author_image: fb.currentUser.photoURL,
|
||||
name: setting,
|
||||
value
|
||||
};
|
||||
value,
|
||||
}
|
||||
usersCollection
|
||||
.doc(fb.currentUser.uid)
|
||||
.collection("settings")
|
||||
.doc(setting)
|
||||
.set(st)
|
||||
.catch(e => console.error("error updating", st, e));
|
||||
.catch(e => console.error("error updating", st, e))
|
||||
},
|
||||
writeHistory: async entry => {
|
||||
const hs = entry;
|
||||
const hs = entry
|
||||
usersCollection
|
||||
.doc(fb.currentUser.uid)
|
||||
.collection("history")
|
||||
.add(hs)
|
||||
.catch(e => console.error("error inserting", hs, e));
|
||||
.catch(e => console.error("error inserting", hs, e))
|
||||
},
|
||||
deleteHistory: entry => {
|
||||
usersCollection
|
||||
@@ -80,7 +80,7 @@ export const fb = {
|
||||
.collection("history")
|
||||
.doc(entry.id)
|
||||
.delete()
|
||||
.catch(e => console.error("error deleting", entry, e));
|
||||
.catch(e => console.error("error deleting", entry, e))
|
||||
},
|
||||
clearHistory: () => {
|
||||
usersCollection
|
||||
@@ -88,8 +88,8 @@ export const fb = {
|
||||
.collection("history")
|
||||
.get()
|
||||
.then(({ docs }) => {
|
||||
docs.forEach(e => fb.deleteHistory(e));
|
||||
});
|
||||
docs.forEach(e => fb.deleteHistory(e))
|
||||
})
|
||||
},
|
||||
toggleStar: (entry, value) => {
|
||||
usersCollection
|
||||
@@ -97,7 +97,7 @@ export const fb = {
|
||||
.collection("history")
|
||||
.doc(entry.id)
|
||||
.update({ star: value })
|
||||
.catch(e => console.error("error deleting", entry, e));
|
||||
.catch(e => console.error("error deleting", entry, e))
|
||||
},
|
||||
writeCollections: async collection => {
|
||||
const cl = {
|
||||
@@ -105,14 +105,14 @@ export const fb = {
|
||||
author: fb.currentUser.uid,
|
||||
author_name: fb.currentUser.displayName,
|
||||
author_image: fb.currentUser.photoURL,
|
||||
collection: collection
|
||||
};
|
||||
collection: collection,
|
||||
}
|
||||
usersCollection
|
||||
.doc(fb.currentUser.uid)
|
||||
.collection("collections")
|
||||
.doc("sync")
|
||||
.set(cl)
|
||||
.catch(e => console.error("error updating", cl, e));
|
||||
.catch(e => console.error("error updating", cl, e))
|
||||
},
|
||||
writeEnvironments: async environment => {
|
||||
const ev = {
|
||||
@@ -120,21 +120,21 @@ export const fb = {
|
||||
author: fb.currentUser.uid,
|
||||
author_name: fb.currentUser.displayName,
|
||||
author_image: fb.currentUser.photoURL,
|
||||
environment: environment
|
||||
};
|
||||
environment: environment,
|
||||
}
|
||||
usersCollection
|
||||
.doc(fb.currentUser.uid)
|
||||
.collection("environments")
|
||||
.doc("sync")
|
||||
.set(ev)
|
||||
.catch(e => console.error("error updating", ev, e));
|
||||
}
|
||||
};
|
||||
.catch(e => console.error("error updating", ev, e))
|
||||
},
|
||||
}
|
||||
|
||||
// When a user logs in or out, save that in the store
|
||||
firebase.auth().onAuthStateChanged(user => {
|
||||
if (user) {
|
||||
fb.currentUser = user;
|
||||
fb.currentUser = user
|
||||
fb.currentUser.providerData.forEach(profile => {
|
||||
let us = {
|
||||
updatedOn: new Date(),
|
||||
@@ -142,80 +142,80 @@ firebase.auth().onAuthStateChanged(user => {
|
||||
name: profile.displayName,
|
||||
email: profile.email,
|
||||
photoUrl: profile.photoURL,
|
||||
uid: profile.uid
|
||||
};
|
||||
uid: profile.uid,
|
||||
}
|
||||
usersCollection
|
||||
.doc(fb.currentUser.uid)
|
||||
.set(us)
|
||||
.catch(e => console.error("error updating", us, e));
|
||||
});
|
||||
.catch(e => console.error("error updating", us, e))
|
||||
})
|
||||
|
||||
usersCollection
|
||||
.doc(fb.currentUser.uid)
|
||||
.collection("feeds")
|
||||
.orderBy("createdOn", "desc")
|
||||
.onSnapshot(feedsRef => {
|
||||
const feeds = [];
|
||||
const feeds = []
|
||||
feedsRef.forEach(doc => {
|
||||
const feed = doc.data();
|
||||
feed.id = doc.id;
|
||||
feeds.push(feed);
|
||||
});
|
||||
fb.currentFeeds = feeds;
|
||||
});
|
||||
const feed = doc.data()
|
||||
feed.id = doc.id
|
||||
feeds.push(feed)
|
||||
})
|
||||
fb.currentFeeds = feeds
|
||||
})
|
||||
|
||||
usersCollection
|
||||
.doc(fb.currentUser.uid)
|
||||
.collection("settings")
|
||||
.onSnapshot(settingsRef => {
|
||||
const settings = [];
|
||||
const settings = []
|
||||
settingsRef.forEach(doc => {
|
||||
const setting = doc.data();
|
||||
setting.id = doc.id;
|
||||
settings.push(setting);
|
||||
});
|
||||
fb.currentSettings = settings;
|
||||
});
|
||||
const setting = doc.data()
|
||||
setting.id = doc.id
|
||||
settings.push(setting)
|
||||
})
|
||||
fb.currentSettings = settings
|
||||
})
|
||||
|
||||
usersCollection
|
||||
.doc(fb.currentUser.uid)
|
||||
.collection("history")
|
||||
.onSnapshot(historyRef => {
|
||||
const history = [];
|
||||
const history = []
|
||||
historyRef.forEach(doc => {
|
||||
const entry = doc.data();
|
||||
entry.id = doc.id;
|
||||
history.push(entry);
|
||||
});
|
||||
fb.currentHistory = history;
|
||||
});
|
||||
const entry = doc.data()
|
||||
entry.id = doc.id
|
||||
history.push(entry)
|
||||
})
|
||||
fb.currentHistory = history
|
||||
})
|
||||
|
||||
usersCollection
|
||||
.doc(fb.currentUser.uid)
|
||||
.collection("collections")
|
||||
.onSnapshot(collectionsRef => {
|
||||
const collections = [];
|
||||
const collections = []
|
||||
collectionsRef.forEach(doc => {
|
||||
const collection = doc.data();
|
||||
collection.id = doc.id;
|
||||
collections.push(collection);
|
||||
});
|
||||
fb.currentCollections = collections[0].collection;
|
||||
});
|
||||
const collection = doc.data()
|
||||
collection.id = doc.id
|
||||
collections.push(collection)
|
||||
})
|
||||
fb.currentCollections = collections[0].collection
|
||||
})
|
||||
|
||||
usersCollection
|
||||
.doc(fb.currentUser.uid)
|
||||
.collection("environments")
|
||||
.onSnapshot(environmentsRef => {
|
||||
const environments = [];
|
||||
const environments = []
|
||||
environmentsRef.forEach(doc => {
|
||||
const environment = doc.data();
|
||||
environment.id = doc.id;
|
||||
environments.push(environment);
|
||||
});
|
||||
fb.currentEnvironments = environments[0].environment;
|
||||
});
|
||||
const environment = doc.data()
|
||||
environment.id = doc.id
|
||||
environments.push(environment)
|
||||
})
|
||||
fb.currentEnvironments = environments[0].environment
|
||||
})
|
||||
} else {
|
||||
fb.currentUser = null;
|
||||
fb.currentUser = null
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
@@ -120,5 +120,5 @@ export const commonHeaders = [
|
||||
"X-Pingback",
|
||||
"X-Requested-With",
|
||||
"X-Robots-Tag",
|
||||
"X-UA-Compatible"
|
||||
];
|
||||
"X-UA-Compatible",
|
||||
]
|
||||
|
||||
310
functions/jsonParse.js
Normal file
310
functions/jsonParse.js
Normal file
@@ -0,0 +1,310 @@
|
||||
/**
|
||||
* Copyright (c) 2019 GraphQL Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This JSON parser simply walks the input, generating an AST. Use this in lieu
|
||||
* of JSON.parse if you need character offset parse errors and an AST parse tree
|
||||
* with location information.
|
||||
*
|
||||
* If an error is encountered, a SyntaxError will be thrown, with properties:
|
||||
*
|
||||
* - message: string
|
||||
* - start: int - the start inclusive offset of the syntax error
|
||||
* - end: int - the end exclusive offset of the syntax error
|
||||
*
|
||||
*/
|
||||
export default function jsonParse(str) {
|
||||
string = str
|
||||
strLen = str.length
|
||||
start = end = lastEnd = -1
|
||||
ch()
|
||||
lex()
|
||||
const ast = parseObj()
|
||||
expect("EOF")
|
||||
return ast
|
||||
}
|
||||
|
||||
let string
|
||||
let strLen
|
||||
let start
|
||||
let end
|
||||
let lastEnd
|
||||
let code
|
||||
let kind
|
||||
|
||||
function parseObj() {
|
||||
const nodeStart = start
|
||||
const members = []
|
||||
expect("{")
|
||||
if (!skip("}")) {
|
||||
do {
|
||||
members.push(parseMember())
|
||||
} while (skip(","))
|
||||
expect("}")
|
||||
}
|
||||
return {
|
||||
kind: "Object",
|
||||
start: nodeStart,
|
||||
end: lastEnd,
|
||||
members,
|
||||
}
|
||||
}
|
||||
|
||||
function parseMember() {
|
||||
const nodeStart = start
|
||||
const key = kind === "String" ? curToken() : null
|
||||
expect("String")
|
||||
expect(":")
|
||||
const value = parseVal()
|
||||
return {
|
||||
kind: "Member",
|
||||
start: nodeStart,
|
||||
end: lastEnd,
|
||||
key,
|
||||
value,
|
||||
}
|
||||
}
|
||||
|
||||
function parseArr() {
|
||||
const nodeStart = start
|
||||
const values = []
|
||||
expect("[")
|
||||
if (!skip("]")) {
|
||||
do {
|
||||
values.push(parseVal())
|
||||
} while (skip(","))
|
||||
expect("]")
|
||||
}
|
||||
return {
|
||||
kind: "Array",
|
||||
start: nodeStart,
|
||||
end: lastEnd,
|
||||
values,
|
||||
}
|
||||
}
|
||||
|
||||
function parseVal() {
|
||||
switch (kind) {
|
||||
case "[":
|
||||
return parseArr()
|
||||
case "{":
|
||||
return parseObj()
|
||||
case "String":
|
||||
case "Number":
|
||||
case "Boolean":
|
||||
case "Null":
|
||||
const token = curToken()
|
||||
lex()
|
||||
return token
|
||||
}
|
||||
return expect("Value")
|
||||
}
|
||||
|
||||
function curToken() {
|
||||
return { kind, start, end, value: JSON.parse(string.slice(start, end)) }
|
||||
}
|
||||
|
||||
function expect(str) {
|
||||
if (kind === str) {
|
||||
lex()
|
||||
return
|
||||
}
|
||||
|
||||
let found
|
||||
if (kind === "EOF") {
|
||||
found = "[end of file]"
|
||||
} else if (end - start > 1) {
|
||||
found = "`" + string.slice(start, end) + "`"
|
||||
} else {
|
||||
const match = string.slice(start).match(/^.+?\b/)
|
||||
found = "`" + (match ? match[0] : string[start]) + "`"
|
||||
}
|
||||
|
||||
throw syntaxError(`Expected ${str} but found ${found}.`)
|
||||
}
|
||||
|
||||
function syntaxError(message) {
|
||||
return { message, start, end }
|
||||
}
|
||||
|
||||
function skip(k) {
|
||||
if (kind === k) {
|
||||
lex()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
function ch() {
|
||||
if (end < strLen) {
|
||||
end++
|
||||
code = end === strLen ? 0 : string.charCodeAt(end)
|
||||
}
|
||||
}
|
||||
|
||||
function lex() {
|
||||
lastEnd = end
|
||||
|
||||
while (code === 9 || code === 10 || code === 13 || code === 32) {
|
||||
ch()
|
||||
}
|
||||
|
||||
if (code === 0) {
|
||||
kind = "EOF"
|
||||
return
|
||||
}
|
||||
|
||||
start = end
|
||||
|
||||
switch (code) {
|
||||
// "
|
||||
case 34:
|
||||
kind = "String"
|
||||
return readString()
|
||||
// -, 0-9
|
||||
case 45:
|
||||
case 48:
|
||||
case 49:
|
||||
case 50:
|
||||
case 51:
|
||||
case 52:
|
||||
case 53:
|
||||
case 54:
|
||||
case 55:
|
||||
case 56:
|
||||
case 57:
|
||||
kind = "Number"
|
||||
return readNumber()
|
||||
// f
|
||||
case 102:
|
||||
if (string.slice(start, start + 5) !== "false") {
|
||||
break
|
||||
}
|
||||
end += 4
|
||||
ch()
|
||||
|
||||
kind = "Boolean"
|
||||
return
|
||||
// n
|
||||
case 110:
|
||||
if (string.slice(start, start + 4) !== "null") {
|
||||
break
|
||||
}
|
||||
end += 3
|
||||
ch()
|
||||
|
||||
kind = "Null"
|
||||
return
|
||||
// t
|
||||
case 116:
|
||||
if (string.slice(start, start + 4) !== "true") {
|
||||
break
|
||||
}
|
||||
end += 3
|
||||
ch()
|
||||
|
||||
kind = "Boolean"
|
||||
return
|
||||
}
|
||||
|
||||
kind = string[start]
|
||||
ch()
|
||||
}
|
||||
|
||||
function readString() {
|
||||
ch()
|
||||
while (code !== 34 && code > 31) {
|
||||
if (code === 92) {
|
||||
// \
|
||||
ch()
|
||||
switch (code) {
|
||||
case 34: // "
|
||||
case 47: // /
|
||||
case 92: // \
|
||||
case 98: // b
|
||||
case 102: // f
|
||||
case 110: // n
|
||||
case 114: // r
|
||||
case 116: // t
|
||||
ch()
|
||||
break
|
||||
case 117: // u
|
||||
ch()
|
||||
readHex()
|
||||
readHex()
|
||||
readHex()
|
||||
readHex()
|
||||
break
|
||||
default:
|
||||
throw syntaxError("Bad character escape sequence.")
|
||||
}
|
||||
} else if (end === strLen) {
|
||||
throw syntaxError("Unterminated string.")
|
||||
} else {
|
||||
ch()
|
||||
}
|
||||
}
|
||||
|
||||
if (code === 34) {
|
||||
ch()
|
||||
return
|
||||
}
|
||||
|
||||
throw syntaxError("Unterminated string.")
|
||||
}
|
||||
|
||||
function readHex() {
|
||||
if (
|
||||
(code >= 48 && code <= 57) || // 0-9
|
||||
(code >= 65 && code <= 70) || // A-F
|
||||
(code >= 97 && code <= 102) // a-f
|
||||
) {
|
||||
return ch()
|
||||
}
|
||||
throw syntaxError("Expected hexadecimal digit.")
|
||||
}
|
||||
|
||||
function readNumber() {
|
||||
if (code === 45) {
|
||||
// -
|
||||
ch()
|
||||
}
|
||||
|
||||
if (code === 48) {
|
||||
// 0
|
||||
ch()
|
||||
} else {
|
||||
readDigits()
|
||||
}
|
||||
|
||||
if (code === 46) {
|
||||
// .
|
||||
ch()
|
||||
readDigits()
|
||||
}
|
||||
|
||||
if (code === 69 || code === 101) {
|
||||
// E e
|
||||
ch()
|
||||
if (code === 43 || code === 45) {
|
||||
// + -
|
||||
ch()
|
||||
}
|
||||
readDigits()
|
||||
}
|
||||
}
|
||||
|
||||
function readDigits() {
|
||||
if (code < 48 || code > 57) {
|
||||
// 0 - 9
|
||||
throw syntaxError("Expected decimal digit.")
|
||||
}
|
||||
do {
|
||||
ch()
|
||||
} while (code >= 48 && code <= 57) // 0 - 9
|
||||
}
|
||||
@@ -1,20 +1,16 @@
|
||||
import AxiosStrategy from "./strategies/AxiosStrategy";
|
||||
import ExtensionStrategy, {
|
||||
hasExtensionInstalled
|
||||
} from "./strategies/ExtensionStrategy";
|
||||
import FirefoxStrategy from "./strategies/FirefoxStrategy";
|
||||
import ChromeStrategy, {
|
||||
hasChromeExtensionInstalled
|
||||
} from "./strategies/ChromeStrategy";
|
||||
import AxiosStrategy from "./strategies/AxiosStrategy"
|
||||
import ExtensionStrategy, { hasExtensionInstalled } from "./strategies/ExtensionStrategy"
|
||||
import FirefoxStrategy from "./strategies/FirefoxStrategy"
|
||||
import ChromeStrategy, { hasChromeExtensionInstalled } from "./strategies/ChromeStrategy"
|
||||
|
||||
const isExtensionsAllowed = ({ state }) =>
|
||||
typeof state.postwoman.settings.EXTENSIONS_ENABLED === "undefined" ||
|
||||
state.postwoman.settings.EXTENSIONS_ENABLED;
|
||||
state.postwoman.settings.EXTENSIONS_ENABLED
|
||||
|
||||
const runAppropriateStrategy = (req, store) => {
|
||||
if (isExtensionsAllowed(store)) {
|
||||
if (hasExtensionInstalled()) {
|
||||
return ExtensionStrategy(req, store);
|
||||
return ExtensionStrategy(req, store)
|
||||
}
|
||||
|
||||
// The following strategies are deprecated and kept to support older version of the extensions
|
||||
@@ -22,21 +18,19 @@ const runAppropriateStrategy = (req, store) => {
|
||||
// Chrome Provides a chrome object for scripts to access
|
||||
// Check its availability to say whether you are in Google Chrome
|
||||
if (window.chrome && hasChromeExtensionInstalled()) {
|
||||
return ChromeStrategy(req, store);
|
||||
return ChromeStrategy(req, store)
|
||||
}
|
||||
// The firefox plugin injects a function to send requests through it
|
||||
// If that is available, then we can use the FirefoxStrategy
|
||||
if (window.firefoxExtSendRequest) {
|
||||
return FirefoxStrategy(req, store);
|
||||
return FirefoxStrategy(req, store)
|
||||
}
|
||||
}
|
||||
|
||||
return AxiosStrategy(req, store);
|
||||
};
|
||||
return AxiosStrategy(req, store)
|
||||
}
|
||||
|
||||
const sendNetworkRequest = (req, store) =>
|
||||
runAppropriateStrategy(req, store).finally(() =>
|
||||
window.$nuxt.$loading.finish()
|
||||
);
|
||||
runAppropriateStrategy(req, store).finally(() => window.$nuxt.$loading.finish())
|
||||
|
||||
export { sendNetworkRequest };
|
||||
export { sendNetworkRequest }
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
const PASS = "PASS";
|
||||
const FAIL = "FAIL";
|
||||
const ERROR = "ERROR";
|
||||
const PASS = "PASS"
|
||||
const FAIL = "FAIL"
|
||||
const ERROR = "ERROR"
|
||||
|
||||
const styles = {
|
||||
[PASS]: { icon: "check", class: "success-response" },
|
||||
[FAIL]: { icon: "close", class: "cl-error-response" },
|
||||
[ERROR]: { icon: "close", class: "cl-error-response" },
|
||||
none: { icon: "", class: "" }
|
||||
};
|
||||
none: { icon: "", class: "" },
|
||||
}
|
||||
|
||||
// TODO: probably have to use a more global state for `test`
|
||||
|
||||
@@ -18,158 +18,130 @@ export default function runTestScriptWithVariables(script, variables) {
|
||||
_report: "",
|
||||
expect(value) {
|
||||
try {
|
||||
return expect(value, this._testReports);
|
||||
return expect(value, this._testReports)
|
||||
} catch (e) {
|
||||
pw._testReports.push({ result: ERROR, message: e });
|
||||
pw._testReports.push({ result: ERROR, message: e })
|
||||
}
|
||||
},
|
||||
test: (descriptor, func) => test(descriptor, func, pw._testReports)
|
||||
test: (descriptor, func) => test(descriptor, func, pw._testReports),
|
||||
// globals that the script is allowed to have access to.
|
||||
};
|
||||
Object.assign(pw, variables);
|
||||
}
|
||||
Object.assign(pw, variables)
|
||||
|
||||
// run pre-request script within this function so that it has access to the pw object.
|
||||
new Function("pw", script)(pw);
|
||||
new Function("pw", script)(pw)
|
||||
//
|
||||
const testReports = pw._testReports.map(item => {
|
||||
if (item.result) {
|
||||
item.styles = styles[item.result];
|
||||
item.styles = styles[item.result]
|
||||
} else {
|
||||
item.styles = styles.none;
|
||||
item.styles = styles.none
|
||||
}
|
||||
return item;
|
||||
});
|
||||
return { report: pw._report, errors: pw._errors, testResults: testReports };
|
||||
return item
|
||||
})
|
||||
return { report: pw._report, errors: pw._errors, testResults: testReports }
|
||||
}
|
||||
|
||||
function test(descriptor, func, _testReports) {
|
||||
_testReports.push({ startBlock: descriptor });
|
||||
_testReports.push({ startBlock: descriptor })
|
||||
try {
|
||||
func();
|
||||
func()
|
||||
} catch (e) {
|
||||
_testReports.push({ result: ERROR, message: e });
|
||||
_testReports.push({ result: ERROR, message: e })
|
||||
}
|
||||
_testReports.push({ endBlock: true });
|
||||
_testReports.push({ endBlock: true })
|
||||
|
||||
// TODO: Organize and generate text report of each {descriptor: true} section in testReports.
|
||||
// add checkmark or x depending on if each testReport is pass=true or pass=false
|
||||
}
|
||||
|
||||
function expect(expectValue, _testReports) {
|
||||
return new Expectation(expectValue, null, _testReports);
|
||||
return new Expectation(expectValue, null, _testReports)
|
||||
}
|
||||
|
||||
class Expectation {
|
||||
constructor(expectValue, _not, _testReports) {
|
||||
this.expectValue = expectValue;
|
||||
this.not = _not || new Expectation(this.expectValue, true, _testReports);
|
||||
this._testReports = _testReports; // this values is used within Test.it, which wraps Expectation and passes _testReports value.
|
||||
this.expectValue = expectValue
|
||||
this.not = _not || new Expectation(this.expectValue, true, _testReports)
|
||||
this._testReports = _testReports // this values is used within Test.it, which wraps Expectation and passes _testReports value.
|
||||
this._satisfies = function(expectValue, targetValue) {
|
||||
// Used for testing if two values match the expectation, which could be === OR !==, depending on if not
|
||||
// was used. Expectation#_satisfies prevents the need to have an if(this.not) branch in every test method.
|
||||
// Signature is _satisfies([expectValue,] targetValue): if only one argument is given, it is assumed the targetValue, and expectValue is set to this.expectValue
|
||||
if (!targetValue) {
|
||||
targetValue = expectValue;
|
||||
expectValue = this.expectValue;
|
||||
targetValue = expectValue
|
||||
expectValue = this.expectValue
|
||||
}
|
||||
if (this.not === true) {
|
||||
// test the inverse. this.not is always truthly, but an Expectation that is inverted will always be strictly `true`
|
||||
return expectValue !== targetValue;
|
||||
return expectValue !== targetValue
|
||||
} else {
|
||||
return expectValue === targetValue;
|
||||
return expectValue === targetValue
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
_fmtNot(message) {
|
||||
// given a string with "(not)" in it, replaces with "not" or "", depending if the expectation is expecting the positive or inverse (this._not)
|
||||
if (this.not === true) {
|
||||
return message.replace("(not)", "not ");
|
||||
return message.replace("(not)", "not ")
|
||||
} else {
|
||||
return message.replace("(not)", "");
|
||||
return message.replace("(not)", "")
|
||||
}
|
||||
}
|
||||
_fail(message) {
|
||||
this._testReports.push({ result: FAIL, message });
|
||||
this._testReports.push({ result: FAIL, message })
|
||||
}
|
||||
_pass(message) {
|
||||
this._testReports.push({ result: PASS });
|
||||
this._testReports.push({ result: PASS })
|
||||
}
|
||||
// TEST METHODS DEFINED BELOW
|
||||
// these are the usual methods that would follow expect(...)
|
||||
toBe(value) {
|
||||
return this._satisfies(value)
|
||||
? this._pass()
|
||||
: this._fail(
|
||||
this._fmtNot(`Expected ${this.expectValue} (not)to be ${value}`)
|
||||
);
|
||||
: this._fail(this._fmtNot(`Expected ${this.expectValue} (not)to be ${value}`))
|
||||
}
|
||||
toHaveProperty(value) {
|
||||
return this._satisfies(this.expectValue.hasOwnProperty(value), true)
|
||||
? this._pass()
|
||||
: this._fail(
|
||||
this._fmtNot(
|
||||
`Expected object ${this.expectValue} to (not)have property ${value}`
|
||||
)
|
||||
);
|
||||
this._fmtNot(`Expected object ${this.expectValue} to (not)have property ${value}`)
|
||||
)
|
||||
}
|
||||
toBeLevel2xx() {
|
||||
const code = parseInt(this.expectValue);
|
||||
const code = parseInt(this.expectValue)
|
||||
if (Number.isNaN(code)) {
|
||||
return this._fail(
|
||||
`Expected 200-level status but could not parse value ${this.expectValue}`
|
||||
);
|
||||
return this._fail(`Expected 200-level status but could not parse value ${this.expectValue}`)
|
||||
}
|
||||
return this._satisfies(code >= 200 && code < 300)
|
||||
? this._pass()
|
||||
: this._fail(
|
||||
this._fmtNot(
|
||||
`Expected ${this.expectValue} to (not)be 200-level status`
|
||||
)
|
||||
);
|
||||
: this._fail(this._fmtNot(`Expected ${this.expectValue} to (not)be 200-level status`))
|
||||
}
|
||||
toBeLevel3xx() {
|
||||
const code = parseInt(this.expectValue);
|
||||
const code = parseInt(this.expectValue)
|
||||
if (Number.isNaN(code)) {
|
||||
return this._fail(
|
||||
`Expected 300-level status but could not parse value ${this.expectValue}`
|
||||
);
|
||||
return this._fail(`Expected 300-level status but could not parse value ${this.expectValue}`)
|
||||
}
|
||||
return this._satisfies(code >= 300 && code < 400)
|
||||
? this._pass()
|
||||
: this._fail(
|
||||
this._fmtNot(
|
||||
`Expected ${this.expectValue} to (not)be 300-level status`
|
||||
)
|
||||
);
|
||||
: this._fail(this._fmtNot(`Expected ${this.expectValue} to (not)be 300-level status`))
|
||||
}
|
||||
toBeLevel4xx() {
|
||||
const code = parseInt(this.expectValue);
|
||||
const code = parseInt(this.expectValue)
|
||||
if (Number.isNaN(code)) {
|
||||
return this._fail(
|
||||
`Expected 400-level status but could not parse value ${this.expectValue}`
|
||||
);
|
||||
return this._fail(`Expected 400-level status but could not parse value ${this.expectValue}`)
|
||||
}
|
||||
return this._satisfies(code >= 400 && code < 500)
|
||||
? this._pass()
|
||||
: this._fail(
|
||||
this._fmtNot(
|
||||
`Expected ${this.expectValue} to (not)be 400-level status`
|
||||
)
|
||||
);
|
||||
: this._fail(this._fmtNot(`Expected ${this.expectValue} to (not)be 400-level status`))
|
||||
}
|
||||
toBeLevel5xx() {
|
||||
const code = parseInt(this.expectValue);
|
||||
const code = parseInt(this.expectValue)
|
||||
if (Number.isNaN(code)) {
|
||||
return this._fail(
|
||||
`Expected 500-level status but could not parse value ${this.expectValue}`
|
||||
);
|
||||
return this._fail(`Expected 500-level status but could not parse value ${this.expectValue}`)
|
||||
}
|
||||
return this._satisfies(code >= 500 && code < 600)
|
||||
? this._pass()
|
||||
: this._fail(
|
||||
this._fmtNot(
|
||||
`Expected ${this.expectValue} to (not)be 500-level status`
|
||||
)
|
||||
);
|
||||
: this._fail(this._fmtNot(`Expected ${this.expectValue} to (not)be 500-level status`))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
export default function getEnvironmentVariablesFromScript(script) {
|
||||
let _variables = {};
|
||||
let _variables = {}
|
||||
|
||||
// the pw object is the proxy by which pre-request scripts can pass variables to the request.
|
||||
// for security and control purposes, this is the only way a pre-request script should modify variables.
|
||||
let pw = {
|
||||
environment: {
|
||||
set: (key, value) => (_variables[key] = value)
|
||||
set: (key, value) => (_variables[key] = value),
|
||||
},
|
||||
env: {
|
||||
set: (key, value) => (_variables[key] = value)
|
||||
}
|
||||
set: (key, value) => (_variables[key] = value),
|
||||
},
|
||||
// globals that the script is allowed to have access to.
|
||||
};
|
||||
}
|
||||
|
||||
// run pre-request script within this function so that it has access to the pw object.
|
||||
new Function("pw", script)(pw);
|
||||
new Function("pw", script)(pw)
|
||||
|
||||
return _variables;
|
||||
return _variables
|
||||
}
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import axios from "axios";
|
||||
import axios from "axios"
|
||||
|
||||
const axiosWithProxy = async (req, { state }) => {
|
||||
const { data } = await axios.post(
|
||||
state.postwoman.settings.PROXY_URL || "https://postwoman.apollosoftware.xyz/",
|
||||
req
|
||||
);
|
||||
return data;
|
||||
};
|
||||
)
|
||||
return data
|
||||
}
|
||||
|
||||
const axiosWithoutProxy = async (req, _store) => {
|
||||
const res = await axios(req);
|
||||
return res;
|
||||
};
|
||||
const res = await axios(req)
|
||||
return res
|
||||
}
|
||||
|
||||
const axiosStrategy = (req, store) => {
|
||||
if (store.state.postwoman.settings.PROXY_ENABLED) {
|
||||
return axiosWithProxy(req, store);
|
||||
return axiosWithProxy(req, store)
|
||||
}
|
||||
return axiosWithoutProxy(req, store);
|
||||
};
|
||||
return axiosWithoutProxy(req, store)
|
||||
}
|
||||
|
||||
export default axiosStrategy;
|
||||
export default axiosStrategy
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
const EXTENSION_ID = "amknoiejhlmhancpahfcfcfhllgkpbld";
|
||||
const EXTENSION_ID = "amknoiejhlmhancpahfcfcfhllgkpbld"
|
||||
|
||||
// Check if the Chrome Extension is present
|
||||
// The Chrome extension injects an empty span to help detection.
|
||||
// Also check for the presence of window.chrome object to confirm smooth operations
|
||||
export const hasChromeExtensionInstalled = () =>
|
||||
document.getElementById("chromePWExtensionDetect") !== null;
|
||||
document.getElementById("chromePWExtensionDetect") !== null
|
||||
|
||||
const chromeWithoutProxy = (req, _store) =>
|
||||
new Promise((resolve, reject) => {
|
||||
@@ -13,18 +13,18 @@ const chromeWithoutProxy = (req, _store) =>
|
||||
{
|
||||
messageType: "send-req",
|
||||
data: {
|
||||
config: req
|
||||
}
|
||||
config: req,
|
||||
},
|
||||
},
|
||||
({ data }) => {
|
||||
if (data.error) {
|
||||
reject(data.error);
|
||||
reject(data.error)
|
||||
} else {
|
||||
resolve(data.response);
|
||||
resolve(data.response)
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
const chromeWithProxy = (req, { state }) =>
|
||||
new Promise((resolve, reject) => {
|
||||
@@ -44,20 +44,20 @@ const chromeWithProxy = (req, { state }) =>
|
||||
},
|
||||
({ data }) => {
|
||||
if (data.error) {
|
||||
reject(error);
|
||||
reject(error)
|
||||
} else {
|
||||
resolve(data.response.data);
|
||||
resolve(data.response.data)
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
const chromeStrategy = (req, store) => {
|
||||
if (store.state.postwoman.settings.PROXY_ENABLED) {
|
||||
return chromeWithProxy(req, store);
|
||||
return chromeWithProxy(req, store)
|
||||
} else {
|
||||
return chromeWithoutProxy(req, store);
|
||||
return chromeWithoutProxy(req, store)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default chromeStrategy;
|
||||
export default chromeStrategy
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export const hasExtensionInstalled = () =>
|
||||
typeof window.__POSTWOMAN_EXTENSION_HOOK__ !== "undefined";
|
||||
typeof window.__POSTWOMAN_EXTENSION_HOOK__ !== "undefined"
|
||||
|
||||
const extensionWithProxy = async (req, { state }) => {
|
||||
const { data } = await window.__POSTWOMAN_EXTENSION_HOOK__.sendRequest({
|
||||
@@ -12,15 +12,15 @@ const extensionWithProxy = async (req, { state }) => {
|
||||
};
|
||||
|
||||
const extensionWithoutProxy = async (req, _store) => {
|
||||
const res = await window.__POSTWOMAN_EXTENSION_HOOK__.sendRequest(req);
|
||||
return res;
|
||||
};
|
||||
const res = await window.__POSTWOMAN_EXTENSION_HOOK__.sendRequest(req)
|
||||
return res
|
||||
}
|
||||
|
||||
const extensionStrategy = (req, store) => {
|
||||
if (store.state.postwoman.settings.PROXY_ENABLED) {
|
||||
return extensionWithProxy(req, store);
|
||||
return extensionWithProxy(req, store)
|
||||
}
|
||||
return extensionWithoutProxy(req, store);
|
||||
};
|
||||
return extensionWithoutProxy(req, store)
|
||||
}
|
||||
|
||||
export default extensionStrategy;
|
||||
export default extensionStrategy
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
const firefoxWithProxy = (req, { state }) =>
|
||||
new Promise((resolve, reject) => {
|
||||
const eventListener = event => {
|
||||
window.removeEventListener("firefoxExtSendRequestComplete", event);
|
||||
window.removeEventListener("firefoxExtSendRequestComplete", event)
|
||||
|
||||
if (event.detail.error) {
|
||||
reject(JSON.parse(event.detail.error));
|
||||
reject(JSON.parse(event.detail.error))
|
||||
} else {
|
||||
resolve(JSON.parse(event.detail.response).data);
|
||||
resolve(JSON.parse(event.detail.response).data)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
window.addEventListener("firefoxExtSendRequestComplete", eventListener);
|
||||
window.addEventListener("firefoxExtSendRequestComplete", eventListener)
|
||||
|
||||
window.firefoxExtSendRequest({
|
||||
method: "post",
|
||||
@@ -23,28 +23,25 @@ const firefoxWithProxy = (req, { state }) =>
|
||||
const firefoxWithoutProxy = (req, _store) =>
|
||||
new Promise((resolve, reject) => {
|
||||
const eventListener = ({ detail }) => {
|
||||
window.removeEventListener(
|
||||
"firefoxExtSendRequestComplete",
|
||||
eventListener
|
||||
);
|
||||
window.removeEventListener("firefoxExtSendRequestComplete", eventListener)
|
||||
|
||||
if (detail.error) {
|
||||
reject(JSON.parse(detail.error));
|
||||
reject(JSON.parse(detail.error))
|
||||
} else {
|
||||
resolve(JSON.parse(detail.response));
|
||||
resolve(JSON.parse(detail.response))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
window.addEventListener("firefoxExtSendRequestComplete", eventListener);
|
||||
window.addEventListener("firefoxExtSendRequestComplete", eventListener)
|
||||
|
||||
window.firefoxExtSendRequest(req);
|
||||
});
|
||||
window.firefoxExtSendRequest(req)
|
||||
})
|
||||
|
||||
const firefoxStrategy = (req, store) => {
|
||||
if (store.state.postwoman.settings.PROXY_ENABLED) {
|
||||
return firefoxWithProxy(req, store);
|
||||
return firefoxWithProxy(req, store)
|
||||
}
|
||||
return firefoxWithoutProxy(req, store);
|
||||
};
|
||||
return firefoxWithoutProxy(req, store)
|
||||
}
|
||||
|
||||
export default firefoxStrategy;
|
||||
export default firefoxStrategy
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export default function parseTemplateString(string, variables) {
|
||||
if (!variables || !string) {
|
||||
return string;
|
||||
return string
|
||||
}
|
||||
const searchTerm = /<<([^>]*)>>/g; // "<<myVariable>>"
|
||||
return string.replace(searchTerm, (match, p1) => variables[p1] || "");
|
||||
const searchTerm = /<<([^>]*)>>/g // "<<myVariable>>"
|
||||
return string.replace(searchTerm, (match, p1) => variables[p1] || "")
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
// functions which might be called frequently
|
||||
// NOTE : Don't use lambda functions as this doesn't get bound properly in them, use the 'function (args) {}' format
|
||||
const debounce = (func, delay) => {
|
||||
let inDebounce;
|
||||
let inDebounce
|
||||
return function() {
|
||||
const context = this;
|
||||
const args = arguments;
|
||||
clearTimeout(inDebounce);
|
||||
inDebounce = setTimeout(() => func.apply(context, args), delay);
|
||||
};
|
||||
};
|
||||
const context = this
|
||||
const args = arguments
|
||||
clearTimeout(inDebounce)
|
||||
inDebounce = setTimeout(() => func.apply(context, args), delay)
|
||||
}
|
||||
}
|
||||
|
||||
export default debounce;
|
||||
export default debounce
|
||||
|
||||
Reference in New Issue
Block a user