mirror of
https://github.com/status-im/universal-links-handler.git
synced 2025-02-22 07:38:13 +00:00
add support for express route tests
Signed-off-by: Jakub Sokołowski <jakub@status.im>
This commit is contained in:
parent
45d958e81a
commit
b9001265e7
15
README.md
15
README.md
@ -38,18 +38,13 @@ docker-compose -p whatever -f docker-compose.yml build
|
||||
|
||||
It will build the image and start the container listening on port `8080`
|
||||
|
||||
## Running the tests
|
||||
## Testing
|
||||
|
||||
To run the tests, first start the container, either in `production` or `development` mode.
|
||||
```bash
|
||||
yarn run tests
|
||||
```
|
||||
|
||||
Then you can run `bash tests/run.sh -u localhost:8080` or to run against against the live server
|
||||
`bash tests/run.sh -u http://join.status.im`
|
||||
|
||||
Uses the awesome `https://github.com/robwhitby/shakedown`
|
||||
|
||||
The pipeline is at:
|
||||
|
||||
`https://jenkins.status.im/job/misc/job/universal-links-handler/`
|
||||
CI: https://jenkins.status.im/job/misc/job/universal-links-handler/
|
||||
|
||||
## Deployment
|
||||
|
||||
|
@ -5,7 +5,8 @@
|
||||
"scripts": {
|
||||
"start": "node ./bin/www",
|
||||
"watch": "nodemon ./bin/www",
|
||||
"docker": "docker build -t statusteam/universal-links-handler:deploy ."
|
||||
"docker": "docker build -t statusteam/universal-links-handler:deploy .",
|
||||
"tests": "node -r esm tests/main.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"cookie-parser": "~1.4.3",
|
||||
@ -19,6 +20,9 @@
|
||||
"univeil": "^0.1.14"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodemon": "^1.17.5"
|
||||
"esm": "^3.2.25",
|
||||
"nodemon": "^1.17.5",
|
||||
"supertest": "^4.0.2",
|
||||
"zora": "^3.1.8"
|
||||
}
|
||||
}
|
||||
|
5
resources/links.json
Normal file
5
resources/links.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"getStatus": "https://status.im/get/",
|
||||
"playStore": "https://play.google.com/store/apps/details?id=im.status.ethereum",
|
||||
"appleStore": "https://testflight.apple.com/join/J8EuJmey"
|
||||
}
|
87
tests/main.js
Normal file
87
tests/main.js
Normal file
@ -0,0 +1,87 @@
|
||||
import { test } from 'zora'
|
||||
import request from 'supertest'
|
||||
import app from '../app'
|
||||
import links from '../resources/links.json'
|
||||
import assetLinks from '../resources/assetlinks.json'
|
||||
import appleSiteAssociation from '../resources/apple-app-site-association.json'
|
||||
|
||||
const host = 'join.status.im'
|
||||
const chatKey = 'e139115a1acc72510388fcf7e1cf492784c9a839888b25271465f4f1baa38c2d3997f8fd78828eb8628bc3bb55ababd884c6002d18330d59c404cc9ce3e4fb35'
|
||||
const chatName = 'Lavender Trivial Goral'
|
||||
|
||||
const srv = request(app)
|
||||
|
||||
const get = (path) => (
|
||||
srv.get(path).set('Host', host)
|
||||
)
|
||||
|
||||
test('test chat routes', t => {
|
||||
t.test('/b/ens.domains', async t => {
|
||||
const res = await get('/b/ens.domains')
|
||||
t.equal(res.statusCode, 200, 'returns 200')
|
||||
t.ok(res.text.includes(`href="http://${host}/b/ens.domains"`), 'contains link')
|
||||
t.ok(res.text.includes('Browse to ens.domains in Status'), 'contains text')
|
||||
})
|
||||
|
||||
t.test('/@jakubgs.eth', async t => {
|
||||
const res = await get('/@jakubgs.eth')
|
||||
t.equal(res.statusCode, 200, 'returns 200')
|
||||
t.ok(res.text.includes(`href="http://${host}/@jakubgs.eth"`), 'contains link')
|
||||
t.ok(res.text.includes('Chat and transact with <span>@jakubgs.eth</span> in Status.'), 'contains prompt')
|
||||
})
|
||||
|
||||
t.test(`/0x04${chatKey.substr(0,8)}...`, async t => {
|
||||
const res = await get(`/0x04${chatKey}`)
|
||||
t.equal(res.statusCode, 200, 'returns 200')
|
||||
t.ok(res.text.includes(`href="http://${host}/0x04${chatKey}"`), 'contains link')
|
||||
t.ok(res.text.includes(`Chat and transact with <span>0x04${chatKey}</span> in Status.`), 'contains prompt')
|
||||
t.ok(res.text.includes(chatName), 'contains chat name')
|
||||
})
|
||||
|
||||
t.test('/status-test', async t => {
|
||||
const res = await get('/status-test')
|
||||
t.equal(res.statusCode, 200, 'returns 200')
|
||||
t.ok(res.text.includes(`href="http://${host}/status-test"`), 'contains link')
|
||||
t.ok(res.text.includes('Join public channel <span>#status-test</span> on Status.'), 'contains prompt')
|
||||
})
|
||||
})
|
||||
|
||||
test('test other routes', t => {
|
||||
t.test('/health', async t => {
|
||||
const res = await get('/health')
|
||||
t.equal(res.statusCode, 200, 'returns 200')
|
||||
t.equal(res.text, 'OK', 'returns OK')
|
||||
})
|
||||
|
||||
t.test('/.well-known/assetlinks.json', async t => {
|
||||
const res = await get('/.well-known/assetlinks.json')
|
||||
t.equal(res.statusCode, 200, 'returns 200')
|
||||
t.equal(res.text, JSON.stringify(assetLinks), 'returns asset links')
|
||||
})
|
||||
|
||||
t.test('/.well-known/apple-app-site-association', async t => {
|
||||
const res = await get('/.well-known/apple-app-site-association')
|
||||
t.equal(res.statusCode, 200, 'returns 200')
|
||||
t.equal(res.text, JSON.stringify(appleSiteAssociation), 'returns apple association')
|
||||
})
|
||||
})
|
||||
|
||||
test('catch-all route', t => {
|
||||
t.test('redirects to status.im', async t => {
|
||||
const res = await get('/')
|
||||
t.equal(res.statusCode, 302, 'returns 302')
|
||||
t.equal(res.headers.location, links.getStatus, 'sets location')
|
||||
})
|
||||
|
||||
t.test('redirects to play store', async t => {
|
||||
const res = await get('/').set('user-agent', 'xyz Android xyz')
|
||||
t.equal(res.statusCode, 302, 'returns 302')
|
||||
t.equal(res.headers.location, links.playStore, 'sets location')
|
||||
})
|
||||
|
||||
t.test('redirects to apple store', async t => {
|
||||
const res = await get('/').set('user-agent', 'xyz iPhone xyz')
|
||||
t.equal(res.statusCode, 302, 'returns 302')
|
||||
t.equal(res.headers.location, links.appleStore, 'sets location')
|
||||
})
|
||||
})
|
53
tests/run.sh
53
tests/run.sh
@ -1,53 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
source tests/shakedown.sh
|
||||
|
||||
until $(curl --output /dev/null --silent --head --fail $BASE_URL/health); do
|
||||
printf '.'
|
||||
sleep 1
|
||||
done
|
||||
|
||||
shakedown GET /.well-known/assetlinks.json
|
||||
status 200
|
||||
content_type 'application/json'
|
||||
contains 'sha256_cert_fingerprints'
|
||||
|
||||
shakedown GET /.well-known/apple-app-site-association
|
||||
status 200
|
||||
content_type 'application/json'
|
||||
contains 'im.status.ethereum'
|
||||
|
||||
# Android test
|
||||
shakedown GET / -H "User-Agent: Mozilla/5.0 (Linux; Android 7.0; SM-G892A Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Mobile Safari/537.36"
|
||||
header_contains 'Location' 'https://play.google.com/store/apps/details?id=im.status.ethereum'
|
||||
status 302
|
||||
|
||||
# IOS
|
||||
shakedown GET / -H "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"
|
||||
header_contains 'Location' 'https://testflight.apple.com/join/J8EuJmey'
|
||||
status 302
|
||||
|
||||
# Anything else
|
||||
shakedown GET / -H "User-Agent: Unknown"
|
||||
header_contains 'Location' 'https://status.im'
|
||||
status 302
|
||||
|
||||
|
||||
shakedown GET /chat/public/abc
|
||||
status 200
|
||||
|
||||
shakedown GET /user/blah
|
||||
status 200
|
||||
|
||||
shakedown GET /browse/www.test.com
|
||||
status 200
|
||||
|
||||
shakedown GET /browse/www.test.com/blah/blah
|
||||
status 200
|
||||
|
||||
shakedown GET /health
|
||||
status 200
|
||||
contains 'OK'
|
||||
|
||||
shakedown GET /extension/blah
|
||||
status 200
|
@ -1,149 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -u
|
||||
|
||||
BASE_URL=${SHAKEDOWN_URL:-""}
|
||||
CREDENTIALS=${SHAKEDOWN_CREDENTIALS:-""}
|
||||
|
||||
_usage() {
|
||||
echo '
|
||||
usage: $0 [options...]
|
||||
Options:
|
||||
-u <base URL> Base URL to test.
|
||||
-c <user:password> Credentials for HTTP authentication.
|
||||
'
|
||||
exit 1
|
||||
}
|
||||
|
||||
while getopts 'u:c:' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
u) BASE_URL="$OPTARG";;
|
||||
c) CREDENTIALS="$OPTARG";;
|
||||
*) _usage;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
echo "Starting shakedown of ${BASE_URL:-"[base URL not set]"}"
|
||||
|
||||
STATE=""
|
||||
FAIL_COUNT=0
|
||||
PASS_COUNT=0
|
||||
WORKING_DIR=$(mktemp -d -t shakedown.XXXXXX)
|
||||
RESPONSE_BODY="${WORKING_DIR}/body"
|
||||
RESPONSE_HEADERS="${WORKING_DIR}/headers"
|
||||
|
||||
AUTH=""
|
||||
if [ -n "${CREDENTIALS}" ]; then
|
||||
AUTH="--anyauth --user ${CREDENTIALS}"
|
||||
fi
|
||||
|
||||
CURL="curl -sS ${AUTH} -D ${RESPONSE_HEADERS} --connect-timeout 5 --max-time 30"
|
||||
|
||||
CRED=$(tput setaf 1 2> /dev/null)
|
||||
CGREEN=$(tput setaf 2 2> /dev/null)
|
||||
CDEFAULT=$(tput sgr0 2> /dev/null)
|
||||
|
||||
_pass() {
|
||||
echo " ${CGREEN}✔ ${1}${CDEFAULT}"
|
||||
}
|
||||
|
||||
_fail() {
|
||||
STATE="fail"
|
||||
echo " ${CRED}✘ ${1}${CDEFAULT}"
|
||||
}
|
||||
|
||||
_start_test() {
|
||||
_finish_test
|
||||
STATE="pass"
|
||||
}
|
||||
|
||||
_finish_test() {
|
||||
if [ "$STATE" = "pass" ]; then
|
||||
((PASS_COUNT++))
|
||||
elif [ "$STATE" = "fail" ]; then
|
||||
((FAIL_COUNT++))
|
||||
fi
|
||||
}
|
||||
|
||||
_finish() {
|
||||
_finish_test
|
||||
rm -rf "${WORKING_DIR}"
|
||||
echo
|
||||
MSG="Shakedown complete. ${PASS_COUNT} passed, ${FAIL_COUNT} failed."
|
||||
[[ ${FAIL_COUNT} -eq 0 ]] && echo "${CGREEN}${MSG}${CDEFAULT}" || echo "${CRED}${MSG} You're busted.${CDEFAULT}"
|
||||
exit ${FAIL_COUNT}
|
||||
}
|
||||
|
||||
trap _finish EXIT
|
||||
|
||||
# start test
|
||||
# $1 METHOD
|
||||
# $2 URL
|
||||
# $3..$n Custom CURL options
|
||||
shakedown() {
|
||||
_start_test
|
||||
METHOD="$1"
|
||||
URL="$2"
|
||||
if ! [[ $URL == http* ]]; then
|
||||
URL="${BASE_URL}${URL}"
|
||||
fi
|
||||
echo
|
||||
echo "${METHOD} ${URL}"
|
||||
METHOD_OPT="-X ${METHOD}"
|
||||
if [ "${METHOD}" = "HEAD" ]; then
|
||||
METHOD_OPT="-I"
|
||||
fi
|
||||
${CURL} ${METHOD_OPT} "${@:3}" "${URL}" > ${RESPONSE_BODY}
|
||||
}
|
||||
|
||||
# assertions
|
||||
|
||||
header() {
|
||||
grep -Fq "${1}" "${RESPONSE_HEADERS}" && _pass "header ${1}" || _fail "header ${1}"
|
||||
}
|
||||
|
||||
no_header() {
|
||||
grep -Fq "${1}" "${RESPONSE_HEADERS}" && _fail "no_header ${1}" || _pass "no_header ${1}"
|
||||
}
|
||||
|
||||
status() {
|
||||
STATUS_CODE=$(grep -Eo "^HTTP.+ [1-5][0-9][0-9] " ${RESPONSE_HEADERS} | grep -Eo '[1-5][0-9][0-9]' | tail -n1)
|
||||
[[ "${STATUS_CODE}" = "${1}" ]] && _pass "status ${1}" || _fail "status ${1} (actual: ${STATUS_CODE})"
|
||||
}
|
||||
|
||||
contains() {
|
||||
MSG="contains \"${1}\""
|
||||
grep -Fq "${1}" "${RESPONSE_BODY}" && _pass "${MSG}" || _fail "${MSG}"
|
||||
}
|
||||
|
||||
matches() {
|
||||
MSG="matches \"${1}\""
|
||||
grep -Eq "${1}" "${RESPONSE_BODY}" && _pass "${MSG}" || _fail "${MSG}"
|
||||
}
|
||||
|
||||
content_type() {
|
||||
CT_HEADER="$(_get_header 'Content-Type')"
|
||||
echo "${CT_HEADER}" | grep -Fq "${1}" && _pass "Content-Type: ${1}" || _fail "Content-Type: ${1} (actual: ${CT_HEADER})"
|
||||
}
|
||||
|
||||
header_contains() {
|
||||
HEADER_NAME=${1}
|
||||
HEADER="$(_get_header $HEADER_NAME)"
|
||||
echo "${HEADER}" | grep -Fq "${2}" && _pass "${HEADER_NAME}: ${2}" || _fail "${HEADER_NAME}: ${2} (actual: ${HEADER})"
|
||||
}
|
||||
|
||||
_get_header() {
|
||||
grep -i -F "${1}" "${RESPONSE_HEADERS}" | tr -d '\r'
|
||||
}
|
||||
|
||||
# debug
|
||||
|
||||
print_headers() {
|
||||
cat "${RESPONSE_HEADERS}"
|
||||
}
|
||||
|
||||
print_body() {
|
||||
cat "${RESPONSE_BODY}"
|
||||
}
|
||||
|
95
yarn.lock
95
yarn.lock
@ -82,6 +82,11 @@ async-each@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf"
|
||||
integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
||||
|
||||
atob@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||
@ -318,7 +323,14 @@ color-name@1.1.3:
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
||||
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
||||
|
||||
component-emitter@^1.2.1:
|
||||
combined-stream@^1.0.6:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
component-emitter@^1.2.0, component-emitter@^1.2.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
|
||||
integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
|
||||
@ -368,6 +380,11 @@ cookie@0.3.1:
|
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
|
||||
integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=
|
||||
|
||||
cookiejar@^2.1.0:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c"
|
||||
integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==
|
||||
|
||||
copy-descriptor@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
|
||||
@ -406,7 +423,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@~2.6.9:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^3.2.6:
|
||||
debug@^3.1.0, debug@^3.2.6:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
||||
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
|
||||
@ -450,6 +467,11 @@ define-property@^2.0.2:
|
||||
is-descriptor "^1.0.2"
|
||||
isobject "^3.0.1"
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
|
||||
|
||||
depd@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
|
||||
@ -507,6 +529,11 @@ escape-string-regexp@^1.0.5:
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||
|
||||
esm@^3.2.25:
|
||||
version "3.2.25"
|
||||
resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10"
|
||||
integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==
|
||||
|
||||
etag@~1.8.1:
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||
@ -589,6 +616,11 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
|
||||
assign-symbols "^1.0.0"
|
||||
is-extendable "^1.0.1"
|
||||
|
||||
extend@^3.0.0:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
|
||||
extglob@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543"
|
||||
@ -643,6 +675,20 @@ for-in@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||
integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=
|
||||
|
||||
form-data@^2.3.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
|
||||
integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.6"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
formidable@^1.2.0:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.1.tgz#70fb7ca0290ee6ff961090415f4b3df3d2082659"
|
||||
integrity sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==
|
||||
|
||||
forwarded@~0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
|
||||
@ -1097,7 +1143,7 @@ merge-descriptors@1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
|
||||
integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
|
||||
|
||||
methods@~1.1.2:
|
||||
methods@^1.1.1, methods@^1.1.2, methods@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
|
||||
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
|
||||
@ -1126,7 +1172,7 @@ mime-db@1.43.0:
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58"
|
||||
integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==
|
||||
|
||||
mime-types@~2.1.24:
|
||||
mime-types@^2.1.12, mime-types@~2.1.24:
|
||||
version "2.1.26"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06"
|
||||
integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==
|
||||
@ -1138,6 +1184,11 @@ mime@1.4.1:
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
|
||||
integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==
|
||||
|
||||
mime@^1.4.1:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
||||
|
||||
minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
@ -1407,6 +1458,11 @@ qs@6.5.2:
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
|
||||
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
|
||||
|
||||
qs@^6.5.1:
|
||||
version "6.9.1"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.1.tgz#20082c65cb78223635ab1a9eaca8875a29bf8ec9"
|
||||
integrity sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA==
|
||||
|
||||
range-parser@~1.2.0:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
|
||||
@ -1432,7 +1488,7 @@ rc@^1.0.1, rc@^1.1.6:
|
||||
minimist "^1.2.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
|
||||
readable-stream@^2.0.2:
|
||||
readable-stream@^2.0.2, readable-stream@^2.3.5:
|
||||
version "2.3.7"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
||||
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
|
||||
@ -1736,6 +1792,30 @@ strip-json-comments@~2.0.1:
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
|
||||
|
||||
superagent@^3.8.3:
|
||||
version "3.8.3"
|
||||
resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.8.3.tgz#460ea0dbdb7d5b11bc4f78deba565f86a178e128"
|
||||
integrity sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==
|
||||
dependencies:
|
||||
component-emitter "^1.2.0"
|
||||
cookiejar "^2.1.0"
|
||||
debug "^3.1.0"
|
||||
extend "^3.0.0"
|
||||
form-data "^2.3.1"
|
||||
formidable "^1.2.0"
|
||||
methods "^1.1.1"
|
||||
mime "^1.4.1"
|
||||
qs "^6.5.1"
|
||||
readable-stream "^2.3.5"
|
||||
|
||||
supertest@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/supertest/-/supertest-4.0.2.tgz#c2234dbdd6dc79b6f15b99c8d6577b90e4ce3f36"
|
||||
integrity sha512-1BAbvrOZsGA3YTCWqbmh14L0YEq0EGICX/nBnfkfVJn7SrxQV1I3pMYjSzG9y/7ZU2V9dWqyqk2POwxlb09duQ==
|
||||
dependencies:
|
||||
methods "^1.1.2"
|
||||
superagent "^3.8.3"
|
||||
|
||||
supports-color@^5.3.0, supports-color@^5.5.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||
@ -1972,3 +2052,8 @@ yargs@^13.2.4:
|
||||
which-module "^2.0.0"
|
||||
y18n "^4.0.0"
|
||||
yargs-parser "^13.1.1"
|
||||
|
||||
zora@^3.1.8:
|
||||
version "3.1.8"
|
||||
resolved "https://registry.yarnpkg.com/zora/-/zora-3.1.8.tgz#84cf75a057005931058db43366cad8c75a21f04c"
|
||||
integrity sha512-AArEyKiLWi3eLXW2uRbfPvANfSQgV8VHoCuXCihCTQyUv7brFrghGbsUqKxqucc+QodQ1G2+O8Gpsz8RVpeiRQ==
|
||||
|
Loading…
x
Reference in New Issue
Block a user