mirror of
https://github.com/kremalicious/ipfs.git
synced 2024-12-26 14:47:48 +01:00
test tweaks
This commit is contained in:
parent
459044b620
commit
52659efa97
@ -1,3 +1,18 @@
|
||||
{
|
||||
"extends": ["prettier", "plugin:prettier/recommended", "next/core-web-vitals"]
|
||||
"extends": [
|
||||
"prettier",
|
||||
"plugin:prettier/recommended",
|
||||
"next/core-web-vitals"
|
||||
],
|
||||
"plugins": ["prettier", "testing-library"],
|
||||
"overrides": [
|
||||
// Only uses Testing Library lint rules in test files
|
||||
{
|
||||
"files": [
|
||||
"**/__tests__/**/*.[jt]s?(x)",
|
||||
"**/?(*.)+(spec|test).[jt]s?(x)"
|
||||
],
|
||||
"extends": ["plugin:testing-library/react"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
14
.github/workflows/ci.yml
vendored
14
.github/workflows/ci.yml
vendored
@ -29,3 +29,17 @@ jobs:
|
||||
- run: npm run build
|
||||
env:
|
||||
NEXT_PUBLIC_TYPEKIT_ID: ${{ secrets.NEXT_PUBLIC_TYPEKIT_ID }}
|
||||
|
||||
coverage:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test]
|
||||
if: ${{ success() && github.actor != 'dependabot[bot]' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: coverage
|
||||
|
||||
- uses: paambaati/codeclimate-action@v2.7.5
|
||||
env:
|
||||
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
||||
|
@ -4,6 +4,8 @@
|
||||
> [ipfs.kretschmann.io](https://ipfs.kretschmann.io)
|
||||
|
||||
[![CI](https://github.com/kremalicious/ipfs/actions/workflows/ci.yml/badge.svg)](https://github.com/kremalicious/ipfs/actions/workflows/ci.yml)
|
||||
[![Maintainability](https://api.codeclimate.com/v1/badges/c43bcf37192f95f3a154/maintainability)](https://codeclimate.com/github/kremalicious/ipfs/maintainability)
|
||||
[![Test Coverage](https://api.codeclimate.com/v1/badges/c43bcf37192f95f3a154/test_coverage)](https://codeclimate.com/github/kremalicious/ipfs/test_coverage)
|
||||
|
||||
This repo holds a React app built with [Next.js](https://nextjs.org) serving as the frontpage of [ipfs.kretschmann.io](https://ipfs.kretschmann.io) from where you can add files to IPFS via drag and drop.
|
||||
|
||||
|
@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
presets: ['next/babel', '@babel/preset-typescript']
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
module.exports = {
|
||||
rootDir: '../',
|
||||
transform: {
|
||||
'^.+\\.[jt]sx?$': ['babel-jest', { configFile: './jest/babel.config.js' }]
|
||||
},
|
||||
moduleNameMapper: {
|
||||
'.+\\.(css|styl|less|sass|scss)$': '<rootDir>/jest/__mocks__/styleMock.js',
|
||||
'.+\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
|
||||
'<rootDir>/jest/__mocks__/fileMock.js',
|
||||
'\\.svg': '<rootDir>/jest/__mocks__/svgrMock.js'
|
||||
},
|
||||
testPathIgnorePatterns: [
|
||||
'<rootDir>/.next',
|
||||
'<rootDir>/node_modules',
|
||||
'<rootDir>/build',
|
||||
'<rootDir>/coverage'
|
||||
],
|
||||
setupFilesAfterEnv: ['<rootDir>/jest/setup.ts'],
|
||||
collectCoverageFrom: ['src/**/*.{ts,tsx}', '!src/@types/**/*'],
|
||||
collectCoverage: true,
|
||||
testEnvironment: 'jsdom'
|
||||
}
|
294
package-lock.json
generated
294
package-lock.json
generated
@ -30,8 +30,9 @@
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-next": "11.1.2",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.4.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-testing-library": "^4.12.2",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jest": "^27.1.1",
|
||||
"prettier": "^2.4.0",
|
||||
"typescript": "^4.4.3"
|
||||
@ -3532,6 +3533,12 @@
|
||||
"pretty-format": "^27.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
|
||||
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/json5": {
|
||||
"version": "0.0.29",
|
||||
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||
@ -3617,6 +3624,146 @@
|
||||
"integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/experimental-utils": {
|
||||
"version": "4.31.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.31.1.tgz",
|
||||
"integrity": "sha512-NtoPsqmcSsWty0mcL5nTZXMf7Ei0Xr2MT8jWjXMVgRK0/1qeQ2jZzLFUh4QtyJ4+/lPUyMw5cSfeeME+Zrtp9Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.7",
|
||||
"@typescript-eslint/scope-manager": "4.31.1",
|
||||
"@typescript-eslint/types": "4.31.1",
|
||||
"@typescript-eslint/typescript-estree": "4.31.1",
|
||||
"eslint-scope": "^5.1.1",
|
||||
"eslint-utils": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10.12.0 || >=12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "4.31.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.31.1.tgz",
|
||||
"integrity": "sha512-N1Uhn6SqNtU2XpFSkD4oA+F0PfKdWHyr4bTX0xTj8NRx1314gBDRL1LUuZd5+L3oP+wo6hCbZpaa1in6SwMcVQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "4.31.1",
|
||||
"@typescript-eslint/visitor-keys": "4.31.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^8.10.0 || ^10.13.0 || >=11.10.1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/types": {
|
||||
"version": "4.31.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.31.1.tgz",
|
||||
"integrity": "sha512-kixltt51ZJGKENNW88IY5MYqTBA8FR0Md8QdGbJD2pKZ+D5IvxjTYDNtJPDxFBiXmka2aJsITdB1BtO1fsgmsQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^8.10.0 || ^10.13.0 || >=11.10.1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "4.31.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.1.tgz",
|
||||
"integrity": "sha512-EGHkbsUvjFrvRnusk6yFGqrqMBTue5E5ROnS5puj3laGQPasVUgwhrxfcgkdHNFECHAewpvELE1Gjv0XO3mdWg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "4.31.1",
|
||||
"@typescript-eslint/visitor-keys": "4.31.1",
|
||||
"debug": "^4.3.1",
|
||||
"globby": "^11.0.3",
|
||||
"is-glob": "^4.0.1",
|
||||
"semver": "^7.3.5",
|
||||
"tsutils": "^3.21.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10.12.0 || >=12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "4.31.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.1.tgz",
|
||||
"integrity": "sha512-PCncP8hEqKw6SOJY+3St4LVtoZpPPn+Zlpm7KW5xnviMhdqcsBty4Lsg4J/VECpJjw1CkROaZhH4B8M1OfnXTQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "4.31.1",
|
||||
"eslint-visitor-keys": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^8.10.0 || ^10.13.0 || >=11.10.1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
|
||||
"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"eslint-visitor-keys": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/mysticatea"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": ">=5"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-visitor-keys": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
|
||||
"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/experimental-utils/node_modules/semver": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "4.31.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.31.0.tgz",
|
||||
@ -6120,6 +6267,22 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-testing-library": {
|
||||
"version": "4.12.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-4.12.2.tgz",
|
||||
"integrity": "sha512-lcysxW7I3oXmZIyFP2N1dFMPfuB3qyl3iDcDboCl7U+TAaeG9OOycNSkZUAsDWQLsfEtXYmRbwTH98qSgk6peA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/experimental-utils": "^4.30.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10.12.0 || >=12.0.0",
|
||||
"npm": ">=6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^7.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-scope": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||
@ -6889,6 +7052,12 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/harmony-reflect": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz",
|
||||
"integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
@ -7091,6 +7260,18 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/identity-obj-proxy": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz",
|
||||
"integrity": "sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ=",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"harmony-reflect": "^1.4.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
@ -16122,6 +16303,12 @@
|
||||
"pretty-format": "^27.0.0"
|
||||
}
|
||||
},
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
|
||||
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/json5": {
|
||||
"version": "0.0.29",
|
||||
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||
@ -16207,6 +16394,87 @@
|
||||
"integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==",
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/experimental-utils": {
|
||||
"version": "4.31.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.31.1.tgz",
|
||||
"integrity": "sha512-NtoPsqmcSsWty0mcL5nTZXMf7Ei0Xr2MT8jWjXMVgRK0/1qeQ2jZzLFUh4QtyJ4+/lPUyMw5cSfeeME+Zrtp9Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.7",
|
||||
"@typescript-eslint/scope-manager": "4.31.1",
|
||||
"@typescript-eslint/types": "4.31.1",
|
||||
"@typescript-eslint/typescript-estree": "4.31.1",
|
||||
"eslint-scope": "^5.1.1",
|
||||
"eslint-utils": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": {
|
||||
"version": "4.31.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.31.1.tgz",
|
||||
"integrity": "sha512-N1Uhn6SqNtU2XpFSkD4oA+F0PfKdWHyr4bTX0xTj8NRx1314gBDRL1LUuZd5+L3oP+wo6hCbZpaa1in6SwMcVQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "4.31.1",
|
||||
"@typescript-eslint/visitor-keys": "4.31.1"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/types": {
|
||||
"version": "4.31.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.31.1.tgz",
|
||||
"integrity": "sha512-kixltt51ZJGKENNW88IY5MYqTBA8FR0Md8QdGbJD2pKZ+D5IvxjTYDNtJPDxFBiXmka2aJsITdB1BtO1fsgmsQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/typescript-estree": {
|
||||
"version": "4.31.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.1.tgz",
|
||||
"integrity": "sha512-EGHkbsUvjFrvRnusk6yFGqrqMBTue5E5ROnS5puj3laGQPasVUgwhrxfcgkdHNFECHAewpvELE1Gjv0XO3mdWg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "4.31.1",
|
||||
"@typescript-eslint/visitor-keys": "4.31.1",
|
||||
"debug": "^4.3.1",
|
||||
"globby": "^11.0.3",
|
||||
"is-glob": "^4.0.1",
|
||||
"semver": "^7.3.5",
|
||||
"tsutils": "^3.21.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/visitor-keys": {
|
||||
"version": "4.31.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.1.tgz",
|
||||
"integrity": "sha512-PCncP8hEqKw6SOJY+3St4LVtoZpPPn+Zlpm7KW5xnviMhdqcsBty4Lsg4J/VECpJjw1CkROaZhH4B8M1OfnXTQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "4.31.1",
|
||||
"eslint-visitor-keys": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"eslint-utils": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
|
||||
"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"eslint-visitor-keys": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"eslint-visitor-keys": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
|
||||
"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/parser": {
|
||||
"version": "4.31.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.31.0.tgz",
|
||||
@ -18249,6 +18517,15 @@
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"eslint-plugin-testing-library": {
|
||||
"version": "4.12.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-4.12.2.tgz",
|
||||
"integrity": "sha512-lcysxW7I3oXmZIyFP2N1dFMPfuB3qyl3iDcDboCl7U+TAaeG9OOycNSkZUAsDWQLsfEtXYmRbwTH98qSgk6peA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/experimental-utils": "^4.30.0"
|
||||
}
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||
@ -18710,6 +18987,12 @@
|
||||
"duplexer": "^0.1.2"
|
||||
}
|
||||
},
|
||||
"harmony-reflect": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz",
|
||||
"integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==",
|
||||
"dev": true
|
||||
},
|
||||
"has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
@ -18855,6 +19138,15 @@
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
}
|
||||
},
|
||||
"identity-obj-proxy": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz",
|
||||
"integrity": "sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"harmony-reflect": "^1.4.6"
|
||||
}
|
||||
},
|
||||
"ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
|
@ -6,8 +6,8 @@
|
||||
"start": "next dev",
|
||||
"build": "next build",
|
||||
"serve": "next start",
|
||||
"test": "npm run lint && npm run type-check && NODE_ENV=test jest -c jest/jest.config.js",
|
||||
"test:watch": "npm run lint && npm run type-check && NODE_ENV=test jest -c jest/jest.config.js --watch",
|
||||
"test": "npm run lint && npm run type-check && NODE_ENV=test jest -c test/__config__/jest.config.js",
|
||||
"test:watch": "npm run lint && npm run type-check && NODE_ENV=test jest -c test/__config__/jest.config.js --watch",
|
||||
"lint": "next lint",
|
||||
"type-check": "tsc --noEmit",
|
||||
"format": "prettier --ignore-path .gitignore '**/*.{css,yml,js,jsx,ts,tsx,json}' --write",
|
||||
@ -38,6 +38,8 @@
|
||||
"eslint-config-next": "11.1.2",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-testing-library": "^4.12.2",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jest": "^27.1.1",
|
||||
"prettier": "^2.4.0",
|
||||
"typescript": "^4.4.3"
|
||||
|
@ -1,26 +0,0 @@
|
||||
.add {
|
||||
width: 100%;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.files {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-bottom: calc(var(--spacer) / 4);
|
||||
font-size: var(--font-size-base);
|
||||
}
|
||||
|
||||
.link {
|
||||
color: var(--color-text);
|
||||
font-size: var(--font-size-small);
|
||||
margin-bottom: calc(var(--spacer) / 4);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
color: var(--brand-cyan);
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
import React, { useState, ReactElement } from 'react'
|
||||
import { ipfsGateway } from '../../site.config'
|
||||
import Dropzone from './Dropzone'
|
||||
import styles from './Add.module.css'
|
||||
import Loader from './Loader'
|
||||
import useIpfsApi from '../hooks/use-ipfs-api'
|
||||
import { FileIpfs } from '../@types/ipfs'
|
||||
import { FileWithPath } from 'react-dropzone'
|
||||
|
||||
function FileLink({
|
||||
file,
|
||||
cidFolder,
|
||||
cid
|
||||
}: {
|
||||
file: FileIpfs
|
||||
cidFolder: string
|
||||
cid?: string
|
||||
}) {
|
||||
const title = cid ? `ipfs://${cid}` : `ipfs://${cidFolder}/${file.path}`
|
||||
const href = cid
|
||||
? `${ipfsGateway}/ipfs/${cid}`
|
||||
: `${ipfsGateway}/ipfs/${cidFolder}/${file.path}`
|
||||
|
||||
return cidFolder !== cid ? (
|
||||
<a
|
||||
className={styles.link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href={href}
|
||||
>
|
||||
{title}
|
||||
</a>
|
||||
) : null
|
||||
}
|
||||
|
||||
function Files({ files }: { files: FileIpfs[] }) {
|
||||
const cidFolder = files.filter((file) => file.path === '')[0].cid.toString()
|
||||
|
||||
return (
|
||||
<ul className={styles.files}>
|
||||
{files?.map((file) => (
|
||||
<li key={file.path}>
|
||||
<h3 className={styles.title}>
|
||||
{file.path === '' ? 'Folder with all files' : file.path}
|
||||
</h3>
|
||||
<FileLink
|
||||
file={file}
|
||||
cidFolder={cidFolder}
|
||||
cid={file.cid.toString()}
|
||||
/>
|
||||
<p>
|
||||
<FileLink file={file} cidFolder={cidFolder} />
|
||||
</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
export default function Add(): ReactElement {
|
||||
const { ipfs, isIpfsReady, ipfsError, addFiles } = useIpfsApi()
|
||||
const [files, setFiles] = useState<FileIpfs[]>()
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [message] = useState()
|
||||
const [error, setError] = useState<string>()
|
||||
|
||||
async function handleOnDrop(acceptedFiles: FileWithPath[]): Promise<void> {
|
||||
if (!acceptedFiles || !ipfs || !isIpfsReady) return
|
||||
|
||||
setLoading(true)
|
||||
setError(undefined)
|
||||
|
||||
try {
|
||||
const addedFiles = await addFiles(acceptedFiles)
|
||||
setFiles(addedFiles)
|
||||
setLoading(false)
|
||||
} catch (error) {
|
||||
setError(`Adding to IPFS failed: ${(error as Error).message}`)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.add}>
|
||||
{loading ? (
|
||||
<Loader message={message} />
|
||||
) : files?.length ? (
|
||||
<Files files={files} />
|
||||
) : (
|
||||
<Dropzone
|
||||
multiple
|
||||
handleOnDrop={handleOnDrop}
|
||||
disabled={!isIpfsReady}
|
||||
error={error || ipfsError}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
10
src/components/Add/FileLink.module.css
Normal file
10
src/components/Add/FileLink.module.css
Normal file
@ -0,0 +1,10 @@
|
||||
.link {
|
||||
color: var(--color-text);
|
||||
font-size: var(--font-size-small);
|
||||
margin-bottom: calc(var(--spacer) / 4);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
color: var(--brand-cyan);
|
||||
}
|
30
src/components/Add/FileLink.tsx
Normal file
30
src/components/Add/FileLink.tsx
Normal file
@ -0,0 +1,30 @@
|
||||
import React from 'react'
|
||||
import { ipfsGateway } from '../../../site.config'
|
||||
import { FileIpfs } from '../../@types/ipfs'
|
||||
import styles from './FileLink.module.css'
|
||||
|
||||
export default function FileLink({
|
||||
file,
|
||||
cidFolder,
|
||||
cid
|
||||
}: {
|
||||
file: FileIpfs
|
||||
cidFolder: string
|
||||
cid?: string
|
||||
}) {
|
||||
const title = cid ? `ipfs://${cid}` : `ipfs://${cidFolder}/${file.path}`
|
||||
const href = cid
|
||||
? `${ipfsGateway}/ipfs/${cid}`
|
||||
: `${ipfsGateway}/ipfs/${cidFolder}/${file.path}`
|
||||
|
||||
return cidFolder !== cid ? (
|
||||
<a
|
||||
className={styles.link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href={href}
|
||||
>
|
||||
{title}
|
||||
</a>
|
||||
) : null
|
||||
}
|
8
src/components/Add/Files.module.css
Normal file
8
src/components/Add/Files.module.css
Normal file
@ -0,0 +1,8 @@
|
||||
.files {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-bottom: calc(var(--spacer) / 4);
|
||||
font-size: var(--font-size-base);
|
||||
}
|
28
src/components/Add/Files.tsx
Normal file
28
src/components/Add/Files.tsx
Normal file
@ -0,0 +1,28 @@
|
||||
import React from 'react'
|
||||
import { FileIpfs } from '../../@types/ipfs'
|
||||
import FileLink from './FileLink'
|
||||
import styles from './Files.module.css'
|
||||
|
||||
export default function Files({ files }: { files: FileIpfs[] }) {
|
||||
const cidFolder = files.filter((file) => file.path === '')[0].cid.toString()
|
||||
|
||||
return (
|
||||
<ul className={styles.files}>
|
||||
{files?.map((file) => (
|
||||
<li key={file.path}>
|
||||
<h3 className={styles.title}>
|
||||
{file.path === '' ? 'Folder with all files' : file.path}
|
||||
</h3>
|
||||
<FileLink
|
||||
file={file}
|
||||
cidFolder={cidFolder}
|
||||
cid={file.cid.toString()}
|
||||
/>
|
||||
<p>
|
||||
<FileLink file={file} cidFolder={cidFolder} />
|
||||
</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
6
src/components/Add/index.module.css
Normal file
6
src/components/Add/index.module.css
Normal file
@ -0,0 +1,6 @@
|
||||
.add {
|
||||
width: 100%;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
49
src/components/Add/index.tsx
Normal file
49
src/components/Add/index.tsx
Normal file
@ -0,0 +1,49 @@
|
||||
import React, { useState, ReactElement } from 'react'
|
||||
import Dropzone from './Dropzone'
|
||||
import Loader from '../Loader'
|
||||
import useIpfsApi from '../../hooks/use-ipfs-api'
|
||||
import { FileIpfs } from '../../@types/ipfs'
|
||||
import { FileWithPath } from 'react-dropzone'
|
||||
import Files from './Files'
|
||||
import styles from './index.module.css'
|
||||
|
||||
export default function Add(): ReactElement {
|
||||
const { ipfs, isIpfsReady, ipfsError, addFiles } = useIpfsApi()
|
||||
const [files, setFiles] = useState<FileIpfs[]>()
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [message] = useState()
|
||||
const [error, setError] = useState<string>()
|
||||
|
||||
async function handleOnDrop(acceptedFiles: FileWithPath[]): Promise<void> {
|
||||
if (!acceptedFiles || !ipfs || !isIpfsReady) return
|
||||
|
||||
setLoading(true)
|
||||
setError(undefined)
|
||||
|
||||
try {
|
||||
const addedFiles = await addFiles(acceptedFiles)
|
||||
setFiles(addedFiles)
|
||||
setLoading(false)
|
||||
} catch (error) {
|
||||
setError(`Adding to IPFS failed: ${(error as Error).message}`)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.add}>
|
||||
{loading ? (
|
||||
<Loader message={message} />
|
||||
) : files?.length ? (
|
||||
<Files files={files} />
|
||||
) : (
|
||||
<Dropzone
|
||||
multiple
|
||||
handleOnDrop={handleOnDrop}
|
||||
disabled={!isIpfsReady}
|
||||
error={error || ipfsError}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
@ -66,7 +66,7 @@ export default function useIpfsApi(): IpfsApiValue {
|
||||
setIpfs(ipfs)
|
||||
const version = await ipfs.version()
|
||||
setVersion(version.version)
|
||||
setIpfsReady(Boolean(ipfs && (await ipfs.id())))
|
||||
setIpfsReady(ipfs?.isOnline())
|
||||
} catch (e) {
|
||||
setIpfsError(`IPFS connection error: ${(e as Error).message}`)
|
||||
setIpfsReady(false)
|
||||
|
@ -19,9 +19,3 @@ export async function pingUrl(url: string): Promise<boolean> {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export function parseHTML(str: string): HTMLCollection {
|
||||
const tmp = document.implementation.createHTMLDocument()
|
||||
tmp.body.innerHTML = str
|
||||
return tmp.body.children
|
||||
}
|
||||
|
25
test/Files.test.tsx
Normal file
25
test/Files.test.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import React from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import Files from '../src/components/Add/Files'
|
||||
import { CID } from 'multiformats/cid'
|
||||
|
||||
const files = [
|
||||
{
|
||||
path: 'hello',
|
||||
cid: { toString: () => 'xxx' } as CID,
|
||||
size: 1000
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
cid: { toString: () => 'xxx' } as CID,
|
||||
size: 1000
|
||||
}
|
||||
]
|
||||
|
||||
describe('Files', () => {
|
||||
it('renders without crashing', async () => {
|
||||
render(<Files files={files} />)
|
||||
const element = await screen.findByText('ipfs://xxx/')
|
||||
expect(element).toBeInTheDocument()
|
||||
})
|
||||
})
|
@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import Layout from '../Layout'
|
||||
import Layout from '../src/Layout'
|
||||
|
||||
describe('Layout', () => {
|
||||
it('renders without crashing', () => {
|
@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import Loader from '../components/Loader'
|
||||
import Loader from '../src/components/Loader'
|
||||
|
||||
describe('Loader', () => {
|
||||
it('renders without crashing', async () => {
|
9
test/Typekit.test.tsx
Normal file
9
test/Typekit.test.tsx
Normal file
@ -0,0 +1,9 @@
|
||||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import Typekit from '../src/components/Typekit'
|
||||
|
||||
describe('Typekit', () => {
|
||||
it('renders without crashing', async () => {
|
||||
render(<Typekit />)
|
||||
})
|
||||
})
|
27
test/__config__/jest.config.js
Normal file
27
test/__config__/jest.config.js
Normal file
@ -0,0 +1,27 @@
|
||||
module.exports = {
|
||||
rootDir: '../../',
|
||||
transform: {
|
||||
'^.+\\.[jt]sx?$': ['babel-jest', { presets: ['next/babel'] }]
|
||||
},
|
||||
transformIgnorePatterns: [
|
||||
'/node_modules/',
|
||||
'^.+\\.module\\.(css|sass|scss)$'
|
||||
],
|
||||
moduleNameMapper: {
|
||||
'^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy',
|
||||
'^.+\\.(css|sass|scss)$': '<rootDir>/test/__mocks__/styleMock.js',
|
||||
'.+\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
|
||||
'<rootDir>/test/__mocks__/fileMock.js',
|
||||
'\\.svg': '<rootDir>/test/__mocks__/svgrMock.js'
|
||||
},
|
||||
testPathIgnorePatterns: [
|
||||
'<rootDir>/.next',
|
||||
'<rootDir>/node_modules',
|
||||
'<rootDir>/build',
|
||||
'<rootDir>/coverage'
|
||||
],
|
||||
setupFilesAfterEnv: ['<rootDir>/test/__config__/jest.setup.ts'],
|
||||
collectCoverageFrom: ['src/**/*.{ts,tsx}', '!src/@types/**/*'],
|
||||
collectCoverage: true,
|
||||
testEnvironment: '<rootDir>/test/__config__/jest.env.ts'
|
||||
}
|
18
test/__config__/jest.env.ts
Normal file
18
test/__config__/jest.env.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import Environment from 'jest-environment-jsdom'
|
||||
|
||||
/**
|
||||
* A custom environment to set the TextEncoder required by ipfs-http-client.
|
||||
*/
|
||||
module.exports = class CustomTestEnvironment extends Environment {
|
||||
async setup() {
|
||||
await super.setup()
|
||||
if (typeof this.global.TextEncoder === 'undefined') {
|
||||
const { TextEncoder } = require('util')
|
||||
this.global.TextEncoder = TextEncoder
|
||||
}
|
||||
if (typeof this.global.TextDecoder === 'undefined') {
|
||||
const { TextDecoder } = require('util')
|
||||
this.global.TextDecoder = TextDecoder
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,14 @@
|
||||
import React from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import Home from '../pages'
|
||||
import Home from '../src/pages'
|
||||
|
||||
describe('Home', () => {
|
||||
it('renders without crashing', async () => {
|
||||
render(<Home />)
|
||||
await screen.findAllByTitle('Online', undefined, { timeout: 10000 })
|
||||
const online = await screen.findAllByTitle('Online', undefined, {
|
||||
timeout: 10000
|
||||
})
|
||||
expect(screen.getByText('A public IPFS Gateway')).toBeInTheDocument()
|
||||
expect(online).toBeDefined()
|
||||
})
|
||||
})
|
22
test/use-ipfs.test.tsx
Normal file
22
test/use-ipfs.test.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import React from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import useIpfs from '../src/hooks/use-ipfs-api'
|
||||
|
||||
export default function TestComponent() {
|
||||
const { version, isIpfsReady, ipfsError } = useIpfs()
|
||||
|
||||
return (
|
||||
<div>
|
||||
{isIpfsReady && <span>Ready</span>}
|
||||
{version} - {ipfsError}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
describe('use-ipfs', () => {
|
||||
it('renders without crashing', async () => {
|
||||
render(<TestComponent />)
|
||||
const element = await screen.findByText('Ready')
|
||||
expect(element).toBeInTheDocument()
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue
Block a user