diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index d76ab129f..9d007c451 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -27,6 +27,10 @@ jobs: - name: cypress | Fullstack tests id: e2e-tests run: | + cd backend + yarn install + yarn build + cd .. yarn install yarn run cypress:run --spec $(cypress/parallel-features.sh ${{ matrix.job }} ${{ env.jobs }} ) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7030227c9..cc09544ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,68 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [2.7.0](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/2.6.0...2.7.0) + +- fix(webapp): fix event teaser date from start to end by new components [`#6385`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6385) +- refactor(webapp): optimize create and update event form [`#6381`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6381) +- feat(backend): show events not ended yet [`#6405`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6405) +- feat(backend): migration to add postType property to existing posts [`#6396`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6396) +- feat(backend): seed events [`#6391`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6391) +- feat(backend): seed posts as article [`#6227`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6227) +- refactor(webapp): fix coverage [`#6361`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6361) +- test(other): migrate cypress to v12 [`#6008`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6008) +- refactor(backend): copy files in external script [`#6364`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6364) +- feat(webapp): alternative solution for filter and order posts [`#6367`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6367) +- refactor(webapp): changed color for event-ribbon. [`#6362`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6362) +- fix(webapp): warnings in unit tests [`#6359`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6359) +- Bump metascraper-title from 5.33.5 to 5.34.7 in /backend [`#6372`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6372) +- Bump @babel/preset-env from 7.21.5 to 7.22.4 [`#6369`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6369) +- fix(other): typescript fix regarding dist/build folder 2 [`#6366`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6366) +- fix(backend): corrected path in branded images for backend build folder(former dist) [`#6365`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6365) +- chore(other): upgrade node version in '.nvmrc' files to v20.2.0 [`#6331`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6331) +- feat(backend): typescript [`#6321`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6321) +- fix(webapp): fix group list number to six [`#6319`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6319) +- fix(webapp): fix notification menu comment hash [`#6335`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6335) +- feat(other): 🍰 epic events – master [`#6199`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6199) +- fix(other): fix avatar seeding [`#6260`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6260) +- chore(other): set 'DEBUG=true' in backend '.env.template' to use GraphQL Playground [`#6333`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6333) +- refactor(other): unused packages ocelot [`#6326`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6326) +- refactor(backend): unused packages backend [`#6325`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6325) +- docs(other): add description for script usage in deployment readme [`#6329`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6329) +- fix(webapp): fix newsfeed layout [`#6154`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6154) +- fix(webapp): adds white space after user handle in comment editor [`#6308`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6308) +- Bump validator from 13.0.0 to 13.9.0 in /backend [`#6076`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6076) +- Bump metascraper-soundcloud from 5.34.2 to 5.34.4 in /backend [`#6312`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6312) +- Bump metascraper-audio from 5.33.5 to 5.34.4 in /backend [`#6287`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6287) +- Bump node from 19.9.0-alpine3.17 to 20.2.0-alpine3.17 in /backend [`#6310`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6310) +- docs(other): add missing todo in deployment readme 'TODO-next-update.md' [`#6324`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6324) +- Bump node from 20.1.0-alpine3.17 to 20.2.0-alpine3.17 in /webapp [`#6309`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6309) +- fix(backend): helmet fix [`#6318`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6318) +- fix(backend): helmet + graphiql [`#6303`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6303) +- Bump @babel/preset-env from 7.21.4 to 7.21.5 [`#6273`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6273) +- Bump date-fns from 2.25.0 to 2.30.0 [`#6283`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6283) +- Bump node from 19.9.0-alpine3.17 to 20.1.0-alpine3.17 in /webapp [`#6280`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6280) +- Bump @babel/core from 7.21.4 to 7.21.8 [`#6284`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6284) +- Bump helmet from 3.22.0 to 7.0.0 in /backend [`#6296`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6296) +- fix(webapp): fix z layer of header elements [`#6279`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6279) +- fix(webapp): properly render avatars in group settings [`#6289`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6289) +- fix(backend): post type on notifications [`#6257`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6257) +- fix(backend): recover missing commit [`#6262`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6262) +- feat(backend): filter posts by post type [`#6255`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6255) +- feat(backend): save location address [`#6240`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6240) +- feat(backend): add further event params [`#6231`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6231) +- feat(backend): event parameters [`#6198`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6198) +- feat(backend): create and update posts with labels [`#6197`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6197) +- feat(backend): add article label to posts [`#6196`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6196) +- Cypress: update packaage info [`b38769b`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/b38769b048e9cb9ca07862a61ea810f21b4ce82a) +- update cypress related packageges in package.json [`692ec2a`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/692ec2a11555600647ec8d95b8296c9869948b02) +- fixed coverage reporting [`540cd40`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/540cd40e10ec0461ef17379cb93d914839f3a84f) + #### [2.6.0](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/2.5.1...2.6.0) +> 27 April 2023 + +- chore(release): v2.6.0 [`#6271`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6271) - fix(other): docker-compose for rebranding deployment [`#6265`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6265) - feat(webapp): default categories of group for posts in group [`#6259`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6259) - refactor(webapp): make action radius select in group form a reusable component [`#6244`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6244) diff --git a/backend/.dockerignore b/backend/.dockerignore index 25a941824..a0883bf4d 100644 --- a/backend/.dockerignore +++ b/backend/.dockerignore @@ -12,8 +12,7 @@ docker-compose*.yml ./*.log node_modules/ -scripts/ -dist/ +build/ maintenance-worker/ neo4j/ diff --git a/backend/.gitignore b/backend/.gitignore index 81a29c8e6..833f7e34e 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -3,7 +3,7 @@ node_modules/ .vscode .idea yarn-error.log -dist/* +build/* coverage.lcov .nyc_output/ public/uploads/* diff --git a/backend/.nvmrc b/backend/.nvmrc index cb77acbfe..58b8c2a00 100644 --- a/backend/.nvmrc +++ b/backend/.nvmrc @@ -1 +1 @@ -v19.4.0 \ No newline at end of file +v20.2.0 \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile index 283e6c7fb..fc6c1f4b3 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -74,7 +74,7 @@ FROM code as build # yarn install RUN yarn install --production=false --frozen-lockfile --non-interactive # yarn build -RUN yarn run build +RUN /bin/sh -c "yarn run build" ################################################################################## # TEST ########################################################################### @@ -90,7 +90,7 @@ CMD /bin/sh -c "yarn run dev" FROM base as production # Copy "binary"-files from build image -COPY --from=build ${DOCKER_WORKDIR}/dist ./dist +COPY --from=build ${DOCKER_WORKDIR}/build ./build COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules # Copy static files # TODO - externalize the uploads so we can copy the whole folder diff --git a/backend/jest.config.js b/backend/jest.config.js index 0f8017fb1..9837dca0d 100644 --- a/backend/jest.config.js +++ b/backend/jest.config.js @@ -1,18 +1,19 @@ module.exports = { verbose: true, + preset: 'ts-jest', collectCoverage: true, collectCoverageFrom: [ - '**/*.js', + '**/*.ts', '!**/node_modules/**', '!**/test/**', - '!**/dist/**', - '!**/src/**/?(*.)+(spec|test).js?(x)' + '!**/build/**', + '!**/src/**/?(*.)+(spec|test).ts?(x)' ], coverageThreshold: { global: { lines: 57, }, }, - testMatch: ['**/src/**/?(*.)+(spec|test).js?(x)'], - setupFilesAfterEnv: ['/test/setup.js'] + testMatch: ['**/src/**/?(*.)+(spec|test).ts?(x)'], + setupFilesAfterEnv: ['/test/setup.ts'] } diff --git a/backend/package.json b/backend/package.json index 7d27fb6f8..f236338bd 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,26 +1,26 @@ { "name": "ocelot-social-backend", - "version": "2.6.0", + "version": "2.7.0", "description": "GraphQL Backend for ocelot.social", "repository": "https://github.com/Ocelot-Social-Community/Ocelot-Social", "author": "ocelot.social Community", "license": "MIT", "private": false, - "main": "src/index.js", + "main": "src/index.ts", "scripts": { - "__migrate": "migrate --compiler 'js:@babel/register' --migrations-dir ./src/db/migrations", - "prod:migrate": "migrate --migrations-dir ./dist/db/migrations --store ./dist/db/migrate/store.js", - "start": "node dist/", - "build": "babel src/ -d dist/ --copy-files", - "dev": "nodemon --exec babel-node src/ -e js,gql", - "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/ -e js,gql", + "__migrate": "migrate --compiler 'ts:./src/db/compiler.ts' --migrations-dir ./src/db/migrations", + "prod:migrate": "migrate --migrations-dir ./build/db/migrations --store ./build/db/migrate/store.js", + "start": "node build/", + "build": "tsc && ./scripts/build.copy.files.sh", + "dev": "nodemon --exec ts-node src/ -e js,ts,gql", + "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/ -e js,ts,gql", "lint": "eslint src --config .eslintrc.js", "test": "cross-env NODE_ENV=test NODE_OPTIONS=--max-old-space-size=8192 jest --runInBand --coverage --forceExit --detectOpenHandles", - "db:clean": "babel-node src/db/clean.js", + "db:clean": "ts-node src/db/clean.ts", "db:reset": "yarn run db:clean", - "db:seed": "babel-node src/db/seed.js", - "db:migrate": "yarn run __migrate --store ./src/db/migrate/store.js", - "db:migrate:create": "yarn run __migrate --template-file ./src/db/migrate/template.js --date-format 'yyyymmddHHmmss' create" + "db:seed": "ts-node src/db/seed.ts", + "db:migrate": "yarn run __migrate --store ./src/db/migrate/store.ts", + "db:migrate:create": "yarn run __migrate --template-file ./src/db/migrate/template.ts --date-format 'yyyymmddHHmmss' create" }, "dependencies": { "@babel/cli": "~7.8.4", @@ -72,11 +72,11 @@ "metascraper-logo": "^5.33.5", "metascraper-publisher": "^5.33.5", "metascraper-soundcloud": "^5.34.4", - "metascraper-title": "^5.33.5", + "metascraper-title": "^5.34.7", "metascraper-url": "^5.34.2", "metascraper-video": "^5.33.5", "metascraper-youtube": "^5.33.5", - "migrate": "^1.7.0", + "migrate": "^2.0.0", "mime-types": "^2.1.26", "minimatch": "^3.0.4", "mustache": "^4.2.0", @@ -97,6 +97,8 @@ }, "devDependencies": { "@faker-js/faker": "7.6.0", + "@types/jest": "^29.5.2", + "@types/node": "^20.2.5", "apollo-server-testing": "~2.11.0", "chai": "~4.2.0", "cucumber": "~6.0.5", @@ -112,7 +114,10 @@ "jest": "29.4", "nodemon": "~2.0.2", "prettier": "~2.3.2", - "rosie": "^2.0.1" + "rosie": "^2.0.1", + "ts-jest": "^29.1.0", + "ts-node": "^10.9.1", + "typescript": "^5.0.4" }, "resolutions": { "**/**/fs-capacitor": "^6.2.0", diff --git a/backend/scripts/build.copy.files.sh b/backend/scripts/build.copy.files.sh new file mode 100755 index 000000000..85022ba9b --- /dev/null +++ b/backend/scripts/build.copy.files.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +# html files +mkdir -p build/middleware/helpers/email/templates/ +cp -r src/middleware/helpers/email/templates/*.html build/middleware/helpers/email/templates/ + +mkdir -p build/middleware/helpers/email/templates/en/ +cp -r src/middleware/helpers/email/templates/en/*.html build/middleware/helpers/email/templates/en/ + +mkdir -p build/middleware/helpers/email/templates/de/ +cp -r src/middleware/helpers/email/templates/de/*.html build/middleware/helpers/email/templates/de/ + +# gql files +mkdir -p build/schema/types/ +cp -r src/schema/types/*.gql build/schema/types/ + +mkdir -p build/schema/types/enum/ +cp -r src/schema/types/enum/*.gql build/schema/types/enum/ + +mkdir -p build/schema/types/scalar/ +cp -r src/schema/types/scalar/*.gql build/schema/types/scalar/ + +mkdir -p build/schema/types/type/ +cp -r src/schema/types/type/*.gql build/schema/types/type/ \ No newline at end of file diff --git a/backend/src/activitypub/ActivityPub.js b/backend/src/activitypub/ActivityPub.ts similarity index 95% rename from backend/src/activitypub/ActivityPub.js rename to backend/src/activitypub/ActivityPub.ts index 7ecc9d3fe..5f2bcd8ea 100644 --- a/backend/src/activitypub/ActivityPub.js +++ b/backend/src/activitypub/ActivityPub.ts @@ -11,11 +11,15 @@ import { v4 as uuid } from 'uuid' import CONFIG from '../config' const debug = require('debug')('ea') -let activityPub = null +let activityPub: any = null export { activityPub } export default class ActivityPub { + endpoint: any + dataSource: any + collections: any + host: any constructor(activityPubEndpointUri, internalGraphQlUri) { this.endpoint = activityPubEndpointUri this.dataSource = new NitroDataSource(internalGraphQlUri) @@ -211,16 +215,16 @@ export default class ActivityPub { // serve the rest activity.to.map(async (recipient) => { debug('serve rest') - const actorObject = await this.getActorObject(recipient) + const actorObject: any = await this.getActorObject(recipient) return this.trySend(activity, fromName, new URL(recipient).host, actorObject.inbox) }) } else if (typeof activity.to === 'string') { debug('is string') - const actorObject = await this.getActorObject(activity.to) + const actorObject: any = await this.getActorObject(activity.to) return this.trySend(activity, fromName, new URL(activity.to).host, actorObject.inbox) } else if (Array.isArray(activity.to)) { activity.to.map(async (recipient) => { - const actorObject = await this.getActorObject(recipient) + const actorObject: any = await this.getActorObject(recipient) return this.trySend(activity, fromName, new URL(recipient).host, actorObject.inbox) }) } @@ -231,7 +235,7 @@ export default class ActivityPub { return await signAndSend(activity, fromName, host, url) } catch (e) { if (tries > 0) { - setTimeout(function () { + setTimeout(() => { return this.trySend(activity, fromName, host, url, --tries) }, 20000) } diff --git a/backend/src/activitypub/Collections.js b/backend/src/activitypub/Collections.ts similarity index 97% rename from backend/src/activitypub/Collections.js rename to backend/src/activitypub/Collections.ts index 4040468cf..c0fd6dd71 100644 --- a/backend/src/activitypub/Collections.js +++ b/backend/src/activitypub/Collections.ts @@ -1,4 +1,5 @@ export default class Collections { + dataSource: any constructor(dataSource) { this.dataSource = dataSource } diff --git a/backend/src/activitypub/NitroDataSource.js b/backend/src/activitypub/NitroDataSource.ts similarity index 97% rename from backend/src/activitypub/NitroDataSource.js rename to backend/src/activitypub/NitroDataSource.ts index 476c91439..88b9ae5e9 100644 --- a/backend/src/activitypub/NitroDataSource.js +++ b/backend/src/activitypub/NitroDataSource.ts @@ -17,15 +17,17 @@ import trunc from 'trunc-html' const debug = require('debug')('ea:datasource') export default class NitroDataSource { + uri: any + client: any constructor(uri) { this.uri = uri - const defaultOptions = { + const defaultOptions: any = { query: { fetchPolicy: 'network-only', errorPolicy: 'all', }, } - const link = createHttpLink({ uri: this.uri, fetch: fetch }) // eslint-disable-line + const link = createHttpLink({ uri: this.uri, fetch: fetch } as any) // eslint-disable-line const cache = new InMemoryCache() const authLink = setContext((_, { headers }) => { // generate the authentication token (maybe from env? Which user?) @@ -95,7 +97,7 @@ export default class NitroDataSource { const followers = actor.followedBy const followersCount = actor.followedByCount - const followersCollection = createOrderedCollectionPage(slug, 'followers') + const followersCollection: any = createOrderedCollectionPage(slug, 'followers') followersCollection.totalItems = followersCount debug(`followers = ${JSON.stringify(followers, null, 2)}`) await Promise.all( @@ -157,7 +159,7 @@ export default class NitroDataSource { const following = actor.following const followingCount = actor.followingCount - const followingCollection = createOrderedCollectionPage(slug, 'following') + const followingCollection: any = createOrderedCollectionPage(slug, 'following') followingCollection.totalItems = followingCount await Promise.all( @@ -235,7 +237,7 @@ export default class NitroDataSource { const actor = result.data.User[0] const posts = actor.contributions - const outboxCollection = createOrderedCollectionPage(slug, 'outbox') + const outboxCollection: any = createOrderedCollectionPage(slug, 'outbox') outboxCollection.totalItems = posts.length await Promise.all( posts.map(async (post) => { diff --git a/backend/src/activitypub/routes/inbox.js b/backend/src/activitypub/routes/inbox.ts similarity index 100% rename from backend/src/activitypub/routes/inbox.js rename to backend/src/activitypub/routes/inbox.ts diff --git a/backend/src/activitypub/routes/index.js b/backend/src/activitypub/routes/index.ts similarity index 81% rename from backend/src/activitypub/routes/index.js rename to backend/src/activitypub/routes/index.ts index 00ba7c22d..dc34da3ab 100644 --- a/backend/src/activitypub/routes/index.js +++ b/backend/src/activitypub/routes/index.ts @@ -11,8 +11,8 @@ export default function () { cors(), express.json({ type: ['application/activity+json', 'application/ld+json', 'application/json'], - }), - express.urlencoded({ extended: true }), + }) as any, + express.urlencoded({ extended: true }) as any, user, ) router.use( @@ -20,8 +20,8 @@ export default function () { cors(), express.json({ type: ['application/activity+json', 'application/ld+json', 'application/json'], - }), - express.urlencoded({ extended: true }), + }) as any, + express.urlencoded({ extended: true }) as any, verify, inbox, ) diff --git a/backend/src/activitypub/routes/serveUser.js b/backend/src/activitypub/routes/serveUser.ts similarity index 100% rename from backend/src/activitypub/routes/serveUser.js rename to backend/src/activitypub/routes/serveUser.ts diff --git a/backend/src/activitypub/routes/user.js b/backend/src/activitypub/routes/user.ts similarity index 100% rename from backend/src/activitypub/routes/user.js rename to backend/src/activitypub/routes/user.ts diff --git a/backend/src/activitypub/routes/verify.js b/backend/src/activitypub/routes/verify.ts similarity index 100% rename from backend/src/activitypub/routes/verify.js rename to backend/src/activitypub/routes/verify.ts diff --git a/backend/src/activitypub/routes/webfinger.spec.js b/backend/src/activitypub/routes/webfinger.spec.ts similarity index 100% rename from backend/src/activitypub/routes/webfinger.spec.js rename to backend/src/activitypub/routes/webfinger.spec.ts diff --git a/backend/src/activitypub/routes/webfinger.js b/backend/src/activitypub/routes/webfinger.ts similarity index 98% rename from backend/src/activitypub/routes/webfinger.js rename to backend/src/activitypub/routes/webfinger.ts index 6b8f3e14c..894314f7b 100644 --- a/backend/src/activitypub/routes/webfinger.js +++ b/backend/src/activitypub/routes/webfinger.ts @@ -54,6 +54,6 @@ export async function handler(req, res) { export default function () { const router = express.Router() - router.use('/webfinger', cors(), express.urlencoded({ extended: true }), handler) + router.use('/webfinger', cors(), express.urlencoded({ extended: true }) as any, handler) return router } diff --git a/backend/src/activitypub/security/httpSignature.spec.js b/backend/src/activitypub/security/httpSignature.spec.ts similarity index 100% rename from backend/src/activitypub/security/httpSignature.spec.js rename to backend/src/activitypub/security/httpSignature.spec.ts diff --git a/backend/src/activitypub/security/index.js b/backend/src/activitypub/security/index.ts similarity index 98% rename from backend/src/activitypub/security/index.js rename to backend/src/activitypub/security/index.ts index 399bc7d9b..271aa5995 100644 --- a/backend/src/activitypub/security/index.js +++ b/backend/src/activitypub/security/index.ts @@ -8,7 +8,7 @@ const debug = require('debug')('ea:security') // TODO Does this reference a local config? Why? // dotenv.config({ path: resolve('src', 'activitypub', '.env') }) -export function generateRsaKeyPair(options = {}) { +export function generateRsaKeyPair(options: any = {}) { const { passphrase = CONFIG.PRIVATE_KEY_PASSPHRASE } = options return crypto.generateKeyPairSync('rsa', { modulusLength: 4096, diff --git a/backend/src/activitypub/utils/activity.js b/backend/src/activitypub/utils/activity.ts similarity index 92% rename from backend/src/activitypub/utils/activity.js rename to backend/src/activitypub/utils/activity.ts index 2199361d8..3d85d7f08 100644 --- a/backend/src/activitypub/utils/activity.js +++ b/backend/src/activitypub/utils/activity.ts @@ -100,18 +100,19 @@ export async function getActorId(name) { // } export function isPublicAddressed(postObject) { + const result: { to: any[]} = { to: []} if (typeof postObject.to === 'string') { - postObject.to = [postObject.to] + result.to = [postObject.to] } if (typeof postObject === 'string') { - postObject.to = [postObject] + result.to = [postObject] } if (Array.isArray(postObject)) { - postObject.to = postObject + result.to = postObject } return ( - postObject.to.includes('Public') || - postObject.to.includes('as:Public') || - postObject.to.includes('https://www.w3.org/ns/activitystreams#Public') + result.to.includes('Public') || + result.to.includes('as:Public') || + result.to.includes('https://www.w3.org/ns/activitystreams#Public') ) } diff --git a/backend/src/activitypub/utils/actor.js b/backend/src/activitypub/utils/actor.ts similarity index 100% rename from backend/src/activitypub/utils/actor.js rename to backend/src/activitypub/utils/actor.ts diff --git a/backend/src/activitypub/utils/collection.js b/backend/src/activitypub/utils/collection.ts similarity index 100% rename from backend/src/activitypub/utils/collection.js rename to backend/src/activitypub/utils/collection.ts diff --git a/backend/src/activitypub/utils/index.js b/backend/src/activitypub/utils/index.ts similarity index 99% rename from backend/src/activitypub/utils/index.js rename to backend/src/activitypub/utils/index.ts index aa3ff2101..360125f73 100644 --- a/backend/src/activitypub/utils/index.js +++ b/backend/src/activitypub/utils/index.ts @@ -101,7 +101,7 @@ export function signAndSend(activity, fromName, targetDomain, url) { } else { debug('Response Headers:', JSON.stringify(response.headers, null, 2)) debug('Response Body:', JSON.stringify(response.body, null, 2)) - resolve() + resolve(response) } }, ) diff --git a/backend/src/config/emails.js b/backend/src/config/emails.ts similarity index 100% rename from backend/src/config/emails.js rename to backend/src/config/emails.ts diff --git a/backend/src/config/index.js b/backend/src/config/index.ts similarity index 89% rename from backend/src/config/index.js rename to backend/src/config/index.ts index 7df780cfc..d1dca3781 100644 --- a/backend/src/config/index.js +++ b/backend/src/config/index.ts @@ -1,6 +1,6 @@ import dotenv from 'dotenv' -import emails from './emails.js' -import metadata from './metadata.js' +import emails from './emails' +import metadata from './metadata' // Load env file if (require.resolve) { @@ -15,10 +15,11 @@ if (require.resolve) { } // Use Cypress env or process.env +declare var Cypress: any | undefined const env = typeof Cypress !== 'undefined' ? Cypress.env() : process.env // eslint-disable-line no-undef const environment = { - NODE_ENV: env.NODE_ENV || process.NODE_ENV, + NODE_ENV: env.NODE_ENV || process.env.NODE_ENV, DEBUG: env.NODE_ENV !== 'production' && env.DEBUG, TEST: env.NODE_ENV === 'test', PRODUCTION: env.NODE_ENV === 'production', @@ -90,14 +91,11 @@ const options = { } // Check if all required configs are present -if (require.resolve) { - // are we in a nodejs environment? - Object.entries(required).map((entry) => { - if (!entry[1]) { - throw new Error(`ERROR: "${entry[0]}" env variable is missing.`) - } - }) -} +Object.entries(required).map((entry) => { + if (!entry[1]) { + throw new Error(`ERROR: "${entry[0]}" env variable is missing.`) + } +}) export default { ...environment, diff --git a/backend/src/config/logos.js b/backend/src/config/logos.ts similarity index 76% rename from backend/src/config/logos.js rename to backend/src/config/logos.ts index d093c7b46..41b83b30c 100644 --- a/backend/src/config/logos.js +++ b/backend/src/config/logos.ts @@ -1,4 +1,4 @@ -// this file is duplicated in `backend/src/config/logos.js` and `webapp/constants/logos.js` and replaced on rebranding +// this file is duplicated in `backend/src/config/logos` and `webapp/constants/logos.js` and replaced on rebranding // this are the paths in the webapp export default { LOGO_HEADER_PATH: '/img/custom/logo-horizontal.svg', diff --git a/backend/src/config/metadata.js b/backend/src/config/metadata.ts similarity index 69% rename from backend/src/config/metadata.js rename to backend/src/config/metadata.ts index d40308e80..282fcb655 100644 --- a/backend/src/config/metadata.js +++ b/backend/src/config/metadata.ts @@ -1,4 +1,4 @@ -// this file is duplicated in `backend/src/config/metadata.js` and `webapp/constants/metadata.js` and replaced on rebranding +// this file is duplicated in `backend/src/config/metadata` and `webapp/constants/metadata.js` and replaced on rebranding export default { APPLICATION_NAME: 'ocelot.social', APPLICATION_SHORT_NAME: 'ocelot', diff --git a/backend/src/constants/categories.js b/backend/src/constants/categories.ts similarity index 95% rename from backend/src/constants/categories.js rename to backend/src/constants/categories.ts index 0d61a041a..6365d268a 100644 --- a/backend/src/constants/categories.js +++ b/backend/src/constants/categories.ts @@ -1,4 +1,4 @@ -// this file is duplicated in `backend/src/constants/metadata.js` and `webapp/constants/metadata.js` +// this file is duplicated in `backend/src/constants/metadata` and `webapp/constants/metadata.js` export const CATEGORIES_MIN = 1 export const CATEGORIES_MAX = 3 diff --git a/backend/src/constants/groups.js b/backend/src/constants/groups.ts similarity index 62% rename from backend/src/constants/groups.js rename to backend/src/constants/groups.ts index aec19eac5..b1c305add 100644 --- a/backend/src/constants/groups.js +++ b/backend/src/constants/groups.ts @@ -1,3 +1,3 @@ -// this file is duplicated in `backend/src/constants/group.js` and `webapp/constants/group.js` +// this file is duplicated in `backend/src/constants/group` and `webapp/constants/group.js` export const DESCRIPTION_WITHOUT_HTML_LENGTH_MIN = 50 // with removed HTML tags export const DESCRIPTION_EXCERPT_HTML_LENGTH = 250 // with removed HTML tags diff --git a/backend/src/constants/registration.js b/backend/src/constants/registration.js deleted file mode 100644 index 9e63e478e..000000000 --- a/backend/src/constants/registration.js +++ /dev/null @@ -1,5 +0,0 @@ -// this file is duplicated in `backend/src/config/metadata.js` and `webapp/constants/metadata.js` -export default { - NONCE_LENGTH: 5, - INVITE_CODE_LENGTH: 6, -} diff --git a/backend/src/constants/registration.ts b/backend/src/constants/registration.ts new file mode 100644 index 000000000..a08be3521 --- /dev/null +++ b/backend/src/constants/registration.ts @@ -0,0 +1,5 @@ +// this file is duplicated in `backend/src/config/metadata` and `webapp/constants/metadata.js` +export default { + NONCE_LENGTH: 5, + INVITE_CODE_LENGTH: 6, +} diff --git a/backend/src/db/clean.js b/backend/src/db/clean.ts similarity index 100% rename from backend/src/db/clean.js rename to backend/src/db/clean.ts diff --git a/backend/src/db/compiler.ts b/backend/src/db/compiler.ts new file mode 100644 index 000000000..e01518c3d --- /dev/null +++ b/backend/src/db/compiler.ts @@ -0,0 +1,2 @@ +const tsNode = require('ts-node'); +module.exports = tsNode.register; \ No newline at end of file diff --git a/backend/src/db/factories.js b/backend/src/db/factories.ts similarity index 98% rename from backend/src/db/factories.js rename to backend/src/db/factories.ts index 3f38b5b9c..4ec34e289 100644 --- a/backend/src/db/factories.js +++ b/backend/src/db/factories.ts @@ -4,8 +4,8 @@ import { hashSync } from 'bcryptjs' import { Factory } from 'rosie' import { faker } from '@faker-js/faker' import { getDriver, getNeode } from './neo4j' -import CONFIG from '../config/index.js' -import generateInviteCode from '../schema/resolvers/helpers/generateInviteCode.js' +import CONFIG from '../config/index' +import generateInviteCode from '../schema/resolvers/helpers/generateInviteCode' const neode = getNeode() @@ -15,7 +15,7 @@ const uniqueImageUrl = (imageUrl) => { return newUrl.toString() } -export const cleanDatabase = async (options = {}) => { +export const cleanDatabase = async (options: any = {}) => { const { driver = getDriver() } = options const session = driver.session() try { @@ -165,7 +165,7 @@ Factory.define('post') }) .after(async (buildObject, options) => { const [post, author, image, /* categories, */ tags] = await Promise.all([ - neode.create('Post', buildObject), + neode.create('Article', buildObject), options.author, options.image, // options.categories, diff --git a/backend/src/db/migrate/store.js b/backend/src/db/migrate/store.ts similarity index 100% rename from backend/src/db/migrate/store.js rename to backend/src/db/migrate/store.ts diff --git a/backend/src/db/migrate/template.js b/backend/src/db/migrate/template.ts similarity index 100% rename from backend/src/db/migrate/template.js rename to backend/src/db/migrate/template.ts diff --git a/backend/src/db/migrations-examples/20200123150105-merge_duplicate_user_accounts.js b/backend/src/db/migrations-examples/20200123150105-merge_duplicate_user_accounts.ts similarity index 96% rename from backend/src/db/migrations-examples/20200123150105-merge_duplicate_user_accounts.js rename to backend/src/db/migrations-examples/20200123150105-merge_duplicate_user_accounts.ts index 0914d6b22..7d98d9dcc 100644 --- a/backend/src/db/migrations-examples/20200123150105-merge_duplicate_user_accounts.js +++ b/backend/src/db/migrations-examples/20200123150105-merge_duplicate_user_accounts.ts @@ -18,13 +18,13 @@ export function up(next) { rxSession .beginTransaction() .pipe( - flatMap((txc) => + flatMap((txc: any) => concat( txc .run('MATCH (email:EmailAddress) RETURN email {.email}') .records() .pipe( - map((record) => { + map((record: any) => { const { email } = record.get('email') const normalizedEmail = normalizeEmail(email) return { email, normalizedEmail } @@ -45,7 +45,7 @@ export function up(next) { ) .records() .pipe( - map((r) => ({ + map((r: any) => ({ oldEmail: email, email: r.get('email'), user: r.get('user'), diff --git a/backend/src/db/migrations-examples/20200123150110-merge_duplicate_location_nodes.js b/backend/src/db/migrations-examples/20200123150110-merge_duplicate_location_nodes.ts similarity index 95% rename from backend/src/db/migrations-examples/20200123150110-merge_duplicate_location_nodes.js rename to backend/src/db/migrations-examples/20200123150110-merge_duplicate_location_nodes.ts index 66560ec51..10b77c6dd 100644 --- a/backend/src/db/migrations-examples/20200123150110-merge_duplicate_location_nodes.js +++ b/backend/src/db/migrations-examples/20200123150110-merge_duplicate_location_nodes.ts @@ -12,7 +12,7 @@ export function up(next) { rxSession .beginTransaction() .pipe( - flatMap((transaction) => + flatMap((transaction: any) => concat( transaction .run( @@ -23,7 +23,7 @@ export function up(next) { ) .records() .pipe( - map((record) => { + map((record: any) => { const { id: locationId } = record.get('location') return { locationId } }), @@ -40,7 +40,7 @@ export function up(next) { ) .records() .pipe( - map((record) => ({ + map((record: any) => ({ location: record.get('location'), updatedLocation: record.get('updatedLocation'), })), diff --git a/backend/src/db/migrations-examples/20200127110135-create_muted_relationship_between_existing_blocked_relationships.js b/backend/src/db/migrations-examples/20200127110135-create_muted_relationship_between_existing_blocked_relationships.ts similarity index 100% rename from backend/src/db/migrations-examples/20200127110135-create_muted_relationship_between_existing_blocked_relationships.js rename to backend/src/db/migrations-examples/20200127110135-create_muted_relationship_between_existing_blocked_relationships.ts diff --git a/backend/src/db/migrations-examples/20200206190233-swap_latitude_with_longitude.js b/backend/src/db/migrations-examples/20200206190233-swap_latitude_with_longitude.ts similarity index 100% rename from backend/src/db/migrations-examples/20200206190233-swap_latitude_with_longitude.js rename to backend/src/db/migrations-examples/20200206190233-swap_latitude_with_longitude.ts diff --git a/backend/src/db/migrations-examples/20200207080200-fulltext_index_for_tags.js b/backend/src/db/migrations-examples/20200207080200-fulltext_index_for_tags.ts similarity index 100% rename from backend/src/db/migrations-examples/20200207080200-fulltext_index_for_tags.js rename to backend/src/db/migrations-examples/20200207080200-fulltext_index_for_tags.ts diff --git a/backend/src/db/migrations-examples/20200213230248-add_unique_index_to_image_url.js b/backend/src/db/migrations-examples/20200213230248-add_unique_index_to_image_url.ts similarity index 100% rename from backend/src/db/migrations-examples/20200213230248-add_unique_index_to_image_url.js rename to backend/src/db/migrations-examples/20200213230248-add_unique_index_to_image_url.ts diff --git a/backend/src/db/migrations-examples/20200312140328-bulk_upload_to_s3.js b/backend/src/db/migrations-examples/20200312140328-bulk_upload_to_s3.ts similarity index 98% rename from backend/src/db/migrations-examples/20200312140328-bulk_upload_to_s3.js rename to backend/src/db/migrations-examples/20200312140328-bulk_upload_to_s3.ts index ee9aba023..356004237 100644 --- a/backend/src/db/migrations-examples/20200312140328-bulk_upload_to_s3.js +++ b/backend/src/db/migrations-examples/20200312140328-bulk_upload_to_s3.ts @@ -3,7 +3,7 @@ import { existsSync, createReadStream } from 'fs' import path from 'path' import { S3 } from 'aws-sdk' import mime from 'mime-types' -import { s3Configs } from '../../config' +import s3Configs from '../../config' import https from 'https' export const description = ` diff --git a/backend/src/db/migrations-examples/20200320200315-refactor_all_images_to_separate_type.js b/backend/src/db/migrations-examples/20200320200315-refactor_all_images_to_separate_type.ts similarity index 100% rename from backend/src/db/migrations-examples/20200320200315-refactor_all_images_to_separate_type.js rename to backend/src/db/migrations-examples/20200320200315-refactor_all_images_to_separate_type.ts diff --git a/backend/src/db/migrations-examples/20200323140300-remove_deleted_users_obsolete_attributes.js b/backend/src/db/migrations-examples/20200323140300-remove_deleted_users_obsolete_attributes.ts similarity index 100% rename from backend/src/db/migrations-examples/20200323140300-remove_deleted_users_obsolete_attributes.js rename to backend/src/db/migrations-examples/20200323140300-remove_deleted_users_obsolete_attributes.ts diff --git a/backend/src/db/migrations-examples/20200323160336-remove_deleted_posts_obsolete_attributes.js b/backend/src/db/migrations-examples/20200323160336-remove_deleted_posts_obsolete_attributes.ts similarity index 100% rename from backend/src/db/migrations-examples/20200323160336-remove_deleted_posts_obsolete_attributes.js rename to backend/src/db/migrations-examples/20200323160336-remove_deleted_posts_obsolete_attributes.ts diff --git a/backend/src/db/migrations-examples/20200326160326-remove_dangling_image_urls.js b/backend/src/db/migrations-examples/20200326160326-remove_dangling_image_urls.ts similarity index 100% rename from backend/src/db/migrations-examples/20200326160326-remove_dangling_image_urls.js rename to backend/src/db/migrations-examples/20200326160326-remove_dangling_image_urls.ts diff --git a/backend/src/db/migrations/1613589876420-null_mutation.js b/backend/src/db/migrations/1613589876420-null_mutation.ts similarity index 100% rename from backend/src/db/migrations/1613589876420-null_mutation.js rename to backend/src/db/migrations/1613589876420-null_mutation.ts diff --git a/backend/src/db/migrations/1614023644903-add-clickedCount-to-posts.js b/backend/src/db/migrations/1614023644903-add-clickedCount-to-posts.ts similarity index 100% rename from backend/src/db/migrations/1614023644903-add-clickedCount-to-posts.js rename to backend/src/db/migrations/1614023644903-add-clickedCount-to-posts.ts diff --git a/backend/src/db/migrations/1614177130817-add-viewedTeaserCount-to-posts.js b/backend/src/db/migrations/1614177130817-add-viewedTeaserCount-to-posts.ts similarity index 100% rename from backend/src/db/migrations/1614177130817-add-viewedTeaserCount-to-posts.js rename to backend/src/db/migrations/1614177130817-add-viewedTeaserCount-to-posts.ts diff --git a/backend/src/db/migrations/20210506150512-add-donations-node.js b/backend/src/db/migrations/20210506150512-add-donations-node.ts similarity index 100% rename from backend/src/db/migrations/20210506150512-add-donations-node.js rename to backend/src/db/migrations/20210506150512-add-donations-node.ts diff --git a/backend/src/db/migrations/20210923140939-add-sendNotificationEmails-property-to-all-users.js b/backend/src/db/migrations/20210923140939-add-sendNotificationEmails-property-to-all-users.ts similarity index 100% rename from backend/src/db/migrations/20210923140939-add-sendNotificationEmails-property-to-all-users.js rename to backend/src/db/migrations/20210923140939-add-sendNotificationEmails-property-to-all-users.ts diff --git a/backend/src/db/migrations/20220803060819-create_fulltext_indices_and_unique_keys_for_groups.js b/backend/src/db/migrations/20220803060819-create_fulltext_indices_and_unique_keys_for_groups.ts similarity index 100% rename from backend/src/db/migrations/20220803060819-create_fulltext_indices_and_unique_keys_for_groups.js rename to backend/src/db/migrations/20220803060819-create_fulltext_indices_and_unique_keys_for_groups.ts diff --git a/backend/src/db/migrations/20230320130345-fulltext-search-indexes.js b/backend/src/db/migrations/20230320130345-fulltext-search-indexes.ts similarity index 100% rename from backend/src/db/migrations/20230320130345-fulltext-search-indexes.js rename to backend/src/db/migrations/20230320130345-fulltext-search-indexes.ts diff --git a/backend/src/db/migrations/20230329150329-article-label-for-posts.js b/backend/src/db/migrations/20230329150329-article-label-for-posts.ts similarity index 100% rename from backend/src/db/migrations/20230329150329-article-label-for-posts.js rename to backend/src/db/migrations/20230329150329-article-label-for-posts.ts diff --git a/backend/src/db/migrations/20230608130637-add-postType-property.ts b/backend/src/db/migrations/20230608130637-add-postType-property.ts new file mode 100644 index 000000000..433577715 --- /dev/null +++ b/backend/src/db/migrations/20230608130637-add-postType-property.ts @@ -0,0 +1,53 @@ +import { getDriver } from '../../db/neo4j' + +export const description = 'Add postType property Article to all posts' + +export async function up(next) { + const driver = getDriver() + const session = driver.session() + const transaction = session.beginTransaction() + + try { + await transaction.run(` + MATCH (post:Post) + SET post.postType = 'Article' + RETURN post + `) + await transaction.commit() + next() + } catch (error) { + // eslint-disable-next-line no-console + console.log(error) + await transaction.rollback() + // eslint-disable-next-line no-console + console.log('rolled back') + throw new Error(error) + } finally { + session.close() + } +} + +export async function down(next) { + const driver = getDriver() + const session = driver.session() + const transaction = session.beginTransaction() + + try { + await transaction.run(` + MATCH (post:Post) + REMOVE post.postType + RETURN post + `) + await transaction.commit() + next() + } catch (error) { + // eslint-disable-next-line no-console + console.log(error) + await transaction.rollback() + // eslint-disable-next-line no-console + console.log('rolled back') + throw new Error(error) + } finally { + session.close() + } +} diff --git a/backend/src/db/neo4j.js b/backend/src/db/neo4j.ts similarity index 94% rename from backend/src/db/neo4j.js rename to backend/src/db/neo4j.ts index 6d46a0279..78b52237e 100644 --- a/backend/src/db/neo4j.js +++ b/backend/src/db/neo4j.ts @@ -23,6 +23,7 @@ export function getNeode(options = {}) { if (!neodeInstance) { const { uri, username, password } = { ...defaultOptions, ...options } neodeInstance = new Neode(uri, username, password).with(models) + neodeInstance.extend('Post', 'Article', {}) return neodeInstance } return neodeInstance diff --git a/backend/src/db/seed.js b/backend/src/db/seed.ts similarity index 94% rename from backend/src/db/seed.js rename to backend/src/db/seed.ts index a8f8b9c68..9eb67abbf 100644 --- a/backend/src/db/seed.js +++ b/backend/src/db/seed.ts @@ -596,7 +596,79 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl'] }), ]) - // Create Posts + // Create Events (by peter lustig) + authenticatedUser = await peterLustig.toJson() + const now = new Date() + + await Promise.all([ + mutate({ + mutation: createPostMutation(), + variables: { + id: 'e0', + title: 'Illegaler Kindergeburtstag', + content: 'Elli hat nächste Woche Geburtstag. Wir feiern das!', + categoryIds: ['cat4'], + postType: 'Event', + eventInput: { + eventStart: new Date( + now.getFullYear(), + now.getMonth(), + now.getDate() + 7, + ).toISOString(), + eventVenue: 'Ellis Kinderzimmer', + eventLocationName: 'Deutschland', + }, + }, + }), + mutate({ + mutation: createPostMutation(), + variables: { + id: 'e1', + title: 'Wir Schützen den Stuttgarter Schlossgarten', + content: 'Kein Baum wird gefällt werden!', + categoryIds: ['cat5'], + postType: 'Event', + eventInput: { + eventStart: new Date( + now.getFullYear(), + now.getMonth(), + now.getDate() + 1, + ).toISOString(), + eventVenue: 'Schlossgarten', + eventLocationName: 'Stuttgart', + }, + }, + }), + mutate({ + mutation: createPostMutation(), + variables: { + id: 'e2', + title: 'IT 4 Change Treffen', + content: 'Wir sitzen eine Woche zusammen rum und glotzen uns blöde an.', + categoryIds: ['cat5'], + postType: 'Event', + eventInput: { + eventStart: new Date( + now.getFullYear(), + now.getMonth(), + now.getDate() + 1, + ).toISOString(), + eventEnd: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 4).toISOString(), + eventVenue: 'Ferienlager', + eventLocationName: 'Bahra, Sachsen', + }, + }, + }), + ]) + + let passedEvent = await neode.find('Post', 'e1') + await passedEvent.update({ eventStart: new Date(2010, 8, 30, 10).toISOString() }) + passedEvent = await neode.find('Post', 'e2') + await passedEvent.update({ + eventStart: new Date(now.getFullYear(), now.getMonth(), now.getDate() - 3).toISOString(), + }) + + // Create Posts (Articles) const [p0, p1, p3, p4, p5, p6, p9, p10, p11, p13, p14, p15] = await Promise.all([ Factory.build( diff --git a/backend/src/graphql/authentications.js b/backend/src/graphql/authentications.ts similarity index 100% rename from backend/src/graphql/authentications.js rename to backend/src/graphql/authentications.ts diff --git a/backend/src/graphql/comments.js b/backend/src/graphql/comments.ts similarity index 100% rename from backend/src/graphql/comments.js rename to backend/src/graphql/comments.ts diff --git a/backend/src/graphql/groups.js b/backend/src/graphql/groups.ts similarity index 100% rename from backend/src/graphql/groups.js rename to backend/src/graphql/groups.ts diff --git a/backend/src/graphql/notifications.js b/backend/src/graphql/notifications.ts similarity index 100% rename from backend/src/graphql/notifications.js rename to backend/src/graphql/notifications.ts diff --git a/backend/src/graphql/posts.js b/backend/src/graphql/posts.ts similarity index 100% rename from backend/src/graphql/posts.js rename to backend/src/graphql/posts.ts diff --git a/backend/src/graphql/userManagement.js b/backend/src/graphql/userManagement.ts similarity index 100% rename from backend/src/graphql/userManagement.js rename to backend/src/graphql/userManagement.ts diff --git a/backend/src/helpers/asyncForEach.js b/backend/src/helpers/asyncForEach.ts similarity index 100% rename from backend/src/helpers/asyncForEach.js rename to backend/src/helpers/asyncForEach.ts diff --git a/backend/src/helpers/encryptPassword.js b/backend/src/helpers/encryptPassword.ts similarity index 100% rename from backend/src/helpers/encryptPassword.js rename to backend/src/helpers/encryptPassword.ts diff --git a/backend/src/helpers/jest.js b/backend/src/helpers/jest.ts similarity index 100% rename from backend/src/helpers/jest.js rename to backend/src/helpers/jest.ts diff --git a/backend/src/helpers/walkRecursive.js b/backend/src/helpers/walkRecursive.ts similarity index 94% rename from backend/src/helpers/walkRecursive.js rename to backend/src/helpers/walkRecursive.ts index 26a3a01b2..f560cf9cb 100644 --- a/backend/src/helpers/walkRecursive.js +++ b/backend/src/helpers/walkRecursive.ts @@ -5,7 +5,7 @@ * @property fieldName String * @property callback Function */ -function walkRecursive(data, fields, fieldName, callback, _key) { +function walkRecursive(data, fields, fieldName, callback, _key?) { if (!Array.isArray(fields)) { throw new Error('please provide an fields array for the walkRecursive helper') } diff --git a/backend/src/index.js b/backend/src/index.ts similarity index 100% rename from backend/src/index.js rename to backend/src/index.ts diff --git a/backend/src/jwt/decode.spec.js b/backend/src/jwt/decode.spec.ts similarity index 100% rename from backend/src/jwt/decode.spec.js rename to backend/src/jwt/decode.spec.ts diff --git a/backend/src/jwt/decode.js b/backend/src/jwt/decode.ts similarity index 100% rename from backend/src/jwt/decode.js rename to backend/src/jwt/decode.ts diff --git a/backend/src/jwt/encode.spec.js b/backend/src/jwt/encode.spec.ts similarity index 100% rename from backend/src/jwt/encode.spec.js rename to backend/src/jwt/encode.spec.ts diff --git a/backend/src/jwt/encode.js b/backend/src/jwt/encode.ts similarity index 100% rename from backend/src/jwt/encode.js rename to backend/src/jwt/encode.ts diff --git a/backend/src/middleware/activityPubMiddleware.js b/backend/src/middleware/activityPubMiddleware.ts similarity index 100% rename from backend/src/middleware/activityPubMiddleware.js rename to backend/src/middleware/activityPubMiddleware.ts diff --git a/backend/src/middleware/excerptMiddleware.js b/backend/src/middleware/excerptMiddleware.ts similarity index 100% rename from backend/src/middleware/excerptMiddleware.js rename to backend/src/middleware/excerptMiddleware.ts diff --git a/backend/src/middleware/hashtags/extractHashtags.spec.js b/backend/src/middleware/hashtags/extractHashtags.spec.ts similarity index 100% rename from backend/src/middleware/hashtags/extractHashtags.spec.js rename to backend/src/middleware/hashtags/extractHashtags.spec.ts diff --git a/backend/src/middleware/hashtags/extractHashtags.js b/backend/src/middleware/hashtags/extractHashtags.ts similarity index 93% rename from backend/src/middleware/hashtags/extractHashtags.js rename to backend/src/middleware/hashtags/extractHashtags.ts index 4c7667557..7570802af 100644 --- a/backend/src/middleware/hashtags/extractHashtags.js +++ b/backend/src/middleware/hashtags/extractHashtags.ts @@ -8,7 +8,7 @@ import { exec, build } from 'xregexp/xregexp-all.js' // 2. If it starts with a digit '0-9' than a unicode letter has to follow. const regX = build('^((\\pL+[\\pL0-9]*)|([0-9]+\\pL+[\\pL0-9]*))$') -export default function (content) { +export default function (content?) { if (!content) return [] const $ = cheerio.load(content) // We can not search for class '.hashtag', because the classes are removed at the 'xss' middleware. @@ -18,7 +18,7 @@ export default function (content) { return $(el).attr('data-hashtag-id') }) .get() - const hashtags = [] + const hashtags: any = [] ids.forEach((id) => { const match = exec(id, regX) if (match != null) { diff --git a/backend/src/middleware/hashtags/hashtagsMiddleware.spec.js b/backend/src/middleware/hashtags/hashtagsMiddleware.spec.ts similarity index 100% rename from backend/src/middleware/hashtags/hashtagsMiddleware.spec.js rename to backend/src/middleware/hashtags/hashtagsMiddleware.spec.ts diff --git a/backend/src/middleware/hashtags/hashtagsMiddleware.js b/backend/src/middleware/hashtags/hashtagsMiddleware.ts similarity index 100% rename from backend/src/middleware/hashtags/hashtagsMiddleware.js rename to backend/src/middleware/hashtags/hashtagsMiddleware.ts diff --git a/backend/src/middleware/helpers/cleanHtml.js b/backend/src/middleware/helpers/cleanHtml.ts similarity index 100% rename from backend/src/middleware/helpers/cleanHtml.js rename to backend/src/middleware/helpers/cleanHtml.ts diff --git a/backend/src/middleware/helpers/email/sendMail.js b/backend/src/middleware/helpers/email/sendMail.ts similarity index 95% rename from backend/src/middleware/helpers/email/sendMail.js rename to backend/src/middleware/helpers/email/sendMail.ts index 59d3b090b..359efc91e 100644 --- a/backend/src/middleware/helpers/email/sendMail.js +++ b/backend/src/middleware/helpers/email/sendMail.ts @@ -1,12 +1,12 @@ import CONFIG from '../../../config' -import { cleanHtml } from '../../../middleware/helpers/cleanHtml.js' +import { cleanHtml } from '../../../middleware/helpers/cleanHtml' import nodemailer from 'nodemailer' import { htmlToText } from 'nodemailer-html-to-text' const hasEmailConfig = CONFIG.SMTP_HOST && CONFIG.SMTP_PORT const hasAuthData = CONFIG.SMTP_USERNAME && CONFIG.SMTP_PASSWORD -let sendMailCallback = async () => {} +let sendMailCallback: any = async () => {} if (!hasEmailConfig) { if (!CONFIG.TEST) { // eslint-disable-next-line no-console @@ -29,7 +29,7 @@ if (!hasEmailConfig) { cleanHtml(templateArgs.html, 'dummyKey', { allowedTags: ['a'], allowedAttributes: { a: ['href'] }, - }).replace(/&/g, '&'), + } as any).replace(/&/g, '&'), ) } } diff --git a/backend/src/middleware/helpers/email/templateBuilder.spec.js b/backend/src/middleware/helpers/email/templateBuilder.spec.ts similarity index 99% rename from backend/src/middleware/helpers/email/templateBuilder.spec.js rename to backend/src/middleware/helpers/email/templateBuilder.spec.ts index d5b0edf21..cb516c0a9 100644 --- a/backend/src/middleware/helpers/email/templateBuilder.spec.js +++ b/backend/src/middleware/helpers/email/templateBuilder.spec.ts @@ -1,5 +1,5 @@ import CONFIG from '../../../config' -import logosWebapp from '../../../config/logos.js' +import logosWebapp from '../../../config/logos' import { signupTemplate, emailVerificationTemplate, diff --git a/backend/src/middleware/helpers/email/templateBuilder.js b/backend/src/middleware/helpers/email/templateBuilder.ts similarity index 97% rename from backend/src/middleware/helpers/email/templateBuilder.js rename to backend/src/middleware/helpers/email/templateBuilder.ts index bf174ef48..78d7a9bf9 100644 --- a/backend/src/middleware/helpers/email/templateBuilder.js +++ b/backend/src/middleware/helpers/email/templateBuilder.ts @@ -1,7 +1,7 @@ import mustache from 'mustache' import CONFIG from '../../../config' -import metadata from '../../../config/metadata.js' -import logosWebapp from '../../../config/logos.js' +import metadata from '../../../config/metadata' +import logosWebapp from '../../../config/logos' import * as templates from './templates' import * as templatesEN from './templates/en' diff --git a/backend/src/middleware/helpers/email/templates/de/index.js b/backend/src/middleware/helpers/email/templates/de/index.ts similarity index 100% rename from backend/src/middleware/helpers/email/templates/de/index.js rename to backend/src/middleware/helpers/email/templates/de/index.ts diff --git a/backend/src/middleware/helpers/email/templates/en/index.js b/backend/src/middleware/helpers/email/templates/en/index.ts similarity index 100% rename from backend/src/middleware/helpers/email/templates/en/index.js rename to backend/src/middleware/helpers/email/templates/en/index.ts diff --git a/backend/src/middleware/helpers/email/templates/index.js b/backend/src/middleware/helpers/email/templates/index.ts similarity index 100% rename from backend/src/middleware/helpers/email/templates/index.js rename to backend/src/middleware/helpers/email/templates/index.ts diff --git a/backend/src/middleware/includedFieldsMiddleware.js b/backend/src/middleware/includedFieldsMiddleware.ts similarity index 100% rename from backend/src/middleware/includedFieldsMiddleware.js rename to backend/src/middleware/includedFieldsMiddleware.ts diff --git a/backend/src/middleware/index.js b/backend/src/middleware/index.ts similarity index 100% rename from backend/src/middleware/index.js rename to backend/src/middleware/index.ts diff --git a/backend/src/middleware/languages/languages.spec.js b/backend/src/middleware/languages/languages.spec.ts similarity index 100% rename from backend/src/middleware/languages/languages.spec.js rename to backend/src/middleware/languages/languages.spec.ts diff --git a/backend/src/middleware/languages/languages.js b/backend/src/middleware/languages/languages.ts similarity index 91% rename from backend/src/middleware/languages/languages.js rename to backend/src/middleware/languages/languages.ts index 087252975..83d4e424c 100644 --- a/backend/src/middleware/languages/languages.js +++ b/backend/src/middleware/languages/languages.ts @@ -1,5 +1,5 @@ import LanguageDetect from 'languagedetect' -import { removeHtmlTags } from '../helpers/cleanHtml.js' +import { removeHtmlTags } from '../helpers/cleanHtml' const setPostLanguage = (text) => { const lngDetector = new LanguageDetect() diff --git a/backend/src/middleware/login/loginMiddleware.js b/backend/src/middleware/login/loginMiddleware.ts similarity index 100% rename from backend/src/middleware/login/loginMiddleware.js rename to backend/src/middleware/login/loginMiddleware.ts diff --git a/backend/src/middleware/notifications/mentions/extractMentionedUsers.js b/backend/src/middleware/notifications/mentions/extractMentionedUsers.ts similarity index 100% rename from backend/src/middleware/notifications/mentions/extractMentionedUsers.js rename to backend/src/middleware/notifications/mentions/extractMentionedUsers.ts diff --git a/backend/src/middleware/notifications/notificationsMiddleware.spec.js b/backend/src/middleware/notifications/notificationsMiddleware.spec.ts similarity index 99% rename from backend/src/middleware/notifications/notificationsMiddleware.spec.js rename to backend/src/middleware/notifications/notificationsMiddleware.spec.ts index a9046b09f..f0857ee29 100644 --- a/backend/src/middleware/notifications/notificationsMiddleware.spec.js +++ b/backend/src/middleware/notifications/notificationsMiddleware.spec.ts @@ -576,7 +576,7 @@ describe('notifications', () => { read: false, }, }), - ).resolves.toMatchObject(expected, { errors: undefined }) + ).resolves.toMatchObject({ ...expected, errors: undefined }) }) }) diff --git a/backend/src/middleware/notifications/notificationsMiddleware.js b/backend/src/middleware/notifications/notificationsMiddleware.ts similarity index 98% rename from backend/src/middleware/notifications/notificationsMiddleware.js rename to backend/src/middleware/notifications/notificationsMiddleware.ts index fd8629715..44accbc04 100644 --- a/backend/src/middleware/notifications/notificationsMiddleware.js +++ b/backend/src/middleware/notifications/notificationsMiddleware.ts @@ -238,7 +238,7 @@ const notifyUsersOfMention = async (label, id, idsOfUsers, reason, context) => { [(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors, [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author)} ] AS posts WITH resource, user, notification, authors, posts, - resource {.*, __typename: labels(resource)[0], author: authors[0], post: posts[0]} AS finalResource + resource {.*, __typename: filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'Group'])[0], author: authors[0], post: posts[0]} AS finalResource SET notification.read = FALSE SET notification.createdAt = COALESCE(notification.createdAt, toString(datetime())) SET notification.updatedAt = toString(datetime()) diff --git a/backend/src/middleware/orderByMiddleware.spec.js b/backend/src/middleware/orderByMiddleware.spec.ts similarity index 100% rename from backend/src/middleware/orderByMiddleware.spec.js rename to backend/src/middleware/orderByMiddleware.spec.ts diff --git a/backend/src/middleware/orderByMiddleware.js b/backend/src/middleware/orderByMiddleware.ts similarity index 100% rename from backend/src/middleware/orderByMiddleware.js rename to backend/src/middleware/orderByMiddleware.ts diff --git a/backend/src/middleware/permissionsMiddleware.spec.js b/backend/src/middleware/permissionsMiddleware.spec.ts similarity index 100% rename from backend/src/middleware/permissionsMiddleware.spec.js rename to backend/src/middleware/permissionsMiddleware.spec.ts diff --git a/backend/src/middleware/permissionsMiddleware.js b/backend/src/middleware/permissionsMiddleware.ts similarity index 100% rename from backend/src/middleware/permissionsMiddleware.js rename to backend/src/middleware/permissionsMiddleware.ts diff --git a/backend/src/middleware/sentryMiddleware.js b/backend/src/middleware/sentryMiddleware.ts similarity index 86% rename from backend/src/middleware/sentryMiddleware.js rename to backend/src/middleware/sentryMiddleware.ts index 8891b8677..73f393eef 100644 --- a/backend/src/middleware/sentryMiddleware.js +++ b/backend/src/middleware/sentryMiddleware.ts @@ -1,7 +1,7 @@ import { sentry } from 'graphql-middleware-sentry' import CONFIG from '../config' -let sentryMiddleware = (resolve, root, args, context, resolveInfo) => +let sentryMiddleware: any = (resolve, root, args, context, resolveInfo) => resolve(root, args, context, resolveInfo) if (CONFIG.SENTRY_DSN_BACKEND) { @@ -12,7 +12,7 @@ if (CONFIG.SENTRY_DSN_BACKEND) { release: CONFIG.COMMIT, environment: CONFIG.NODE_ENV, }, - withScope: (scope, error, context) => { + withScope: (scope, error, context: any) => { scope.setUser({ id: context.user && context.user.id, }) diff --git a/backend/src/middleware/sluggifyMiddleware.js b/backend/src/middleware/sluggifyMiddleware.ts similarity index 100% rename from backend/src/middleware/sluggifyMiddleware.js rename to backend/src/middleware/sluggifyMiddleware.ts diff --git a/backend/src/middleware/slugify/uniqueSlug.spec.js b/backend/src/middleware/slugify/uniqueSlug.spec.ts similarity index 100% rename from backend/src/middleware/slugify/uniqueSlug.spec.js rename to backend/src/middleware/slugify/uniqueSlug.spec.ts diff --git a/backend/src/middleware/slugify/uniqueSlug.js b/backend/src/middleware/slugify/uniqueSlug.ts similarity index 100% rename from backend/src/middleware/slugify/uniqueSlug.js rename to backend/src/middleware/slugify/uniqueSlug.ts diff --git a/backend/src/middleware/slugifyMiddleware.spec.js b/backend/src/middleware/slugifyMiddleware.spec.ts similarity index 100% rename from backend/src/middleware/slugifyMiddleware.spec.js rename to backend/src/middleware/slugifyMiddleware.spec.ts diff --git a/backend/src/middleware/softDelete/softDeleteMiddleware.spec.js b/backend/src/middleware/softDelete/softDeleteMiddleware.spec.ts similarity index 100% rename from backend/src/middleware/softDelete/softDeleteMiddleware.spec.js rename to backend/src/middleware/softDelete/softDeleteMiddleware.spec.ts diff --git a/backend/src/middleware/softDelete/softDeleteMiddleware.js b/backend/src/middleware/softDelete/softDeleteMiddleware.ts similarity index 100% rename from backend/src/middleware/softDelete/softDeleteMiddleware.js rename to backend/src/middleware/softDelete/softDeleteMiddleware.ts diff --git a/backend/src/middleware/userInteractions.spec.js b/backend/src/middleware/userInteractions.spec.ts similarity index 100% rename from backend/src/middleware/userInteractions.spec.js rename to backend/src/middleware/userInteractions.spec.ts diff --git a/backend/src/middleware/userInteractions.js b/backend/src/middleware/userInteractions.ts similarity index 100% rename from backend/src/middleware/userInteractions.js rename to backend/src/middleware/userInteractions.ts diff --git a/backend/src/middleware/validation/validationMiddleware.spec.js b/backend/src/middleware/validation/validationMiddleware.spec.ts similarity index 100% rename from backend/src/middleware/validation/validationMiddleware.spec.js rename to backend/src/middleware/validation/validationMiddleware.spec.ts diff --git a/backend/src/middleware/validation/validationMiddleware.js b/backend/src/middleware/validation/validationMiddleware.ts similarity index 97% rename from backend/src/middleware/validation/validationMiddleware.js rename to backend/src/middleware/validation/validationMiddleware.ts index 20933a777..9a56536e7 100644 --- a/backend/src/middleware/validation/validationMiddleware.js +++ b/backend/src/middleware/validation/validationMiddleware.ts @@ -64,7 +64,7 @@ const validateReview = async (resolve, root, args, context, info) => { WHERE resource:User OR resource:Post OR resource:Comment OPTIONAL MATCH (:User)-[filed:FILED]->(:Report {closed: false})-[:BELONGS_TO]->(resource) OPTIONAL MATCH (resource)<-[:WROTE]-(author:User) - RETURN labels(resource)[0] AS label, author, filed + RETURN filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'User'])[0] AS label, author, filed `, { resourceId, diff --git a/backend/src/middleware/xssMiddleware.js b/backend/src/middleware/xssMiddleware.ts similarity index 90% rename from backend/src/middleware/xssMiddleware.js rename to backend/src/middleware/xssMiddleware.ts index 9b15e9712..ede0cc199 100644 --- a/backend/src/middleware/xssMiddleware.js +++ b/backend/src/middleware/xssMiddleware.ts @@ -1,5 +1,5 @@ import walkRecursive from '../helpers/walkRecursive' -import { cleanHtml } from '../middleware/helpers/cleanHtml.js' +import { cleanHtml } from '../middleware/helpers/cleanHtml' // exclamation mark separetes field names, that should not be sanitized const fields = [ diff --git a/backend/src/models/Badge.js b/backend/src/models/Badge.ts similarity index 100% rename from backend/src/models/Badge.js rename to backend/src/models/Badge.ts diff --git a/backend/src/models/Category.js b/backend/src/models/Category.ts similarity index 100% rename from backend/src/models/Category.js rename to backend/src/models/Category.ts diff --git a/backend/src/models/Comment.js b/backend/src/models/Comment.ts similarity index 100% rename from backend/src/models/Comment.js rename to backend/src/models/Comment.ts diff --git a/backend/src/models/Donations.js b/backend/src/models/Donations.ts similarity index 100% rename from backend/src/models/Donations.js rename to backend/src/models/Donations.ts diff --git a/backend/src/models/EmailAddress.js b/backend/src/models/EmailAddress.ts similarity index 100% rename from backend/src/models/EmailAddress.js rename to backend/src/models/EmailAddress.ts diff --git a/backend/src/models/Group.js b/backend/src/models/Group.ts similarity index 100% rename from backend/src/models/Group.js rename to backend/src/models/Group.ts diff --git a/backend/src/models/Image.js b/backend/src/models/Image.ts similarity index 100% rename from backend/src/models/Image.js rename to backend/src/models/Image.ts diff --git a/backend/src/models/InviteCode.js b/backend/src/models/InviteCode.ts similarity index 100% rename from backend/src/models/InviteCode.js rename to backend/src/models/InviteCode.ts diff --git a/backend/src/models/Location.js b/backend/src/models/Location.ts similarity index 100% rename from backend/src/models/Location.js rename to backend/src/models/Location.ts diff --git a/backend/src/models/Migration.js b/backend/src/models/Migration.ts similarity index 100% rename from backend/src/models/Migration.js rename to backend/src/models/Migration.ts diff --git a/backend/src/models/Post.js b/backend/src/models/Post.ts similarity index 95% rename from backend/src/models/Post.js rename to backend/src/models/Post.ts index 235e7d68d..e206ea1f5 100644 --- a/backend/src/models/Post.js +++ b/backend/src/models/Post.ts @@ -57,4 +57,5 @@ export default { }, }, pinned: { type: 'boolean', default: null, valid: [null, true] }, + postType: { type: 'string', default: 'Article', valid: ['Article', 'Event'] }, } diff --git a/backend/src/models/Report.js b/backend/src/models/Report.ts similarity index 100% rename from backend/src/models/Report.js rename to backend/src/models/Report.ts diff --git a/backend/src/models/SocialMedia.js b/backend/src/models/SocialMedia.ts similarity index 100% rename from backend/src/models/SocialMedia.js rename to backend/src/models/SocialMedia.ts diff --git a/backend/src/models/Tag.js b/backend/src/models/Tag.ts similarity index 100% rename from backend/src/models/Tag.js rename to backend/src/models/Tag.ts diff --git a/backend/src/models/UnverifiedEmailAddress.js b/backend/src/models/UnverifiedEmailAddress.ts similarity index 100% rename from backend/src/models/UnverifiedEmailAddress.js rename to backend/src/models/UnverifiedEmailAddress.ts diff --git a/backend/src/models/User.spec.js b/backend/src/models/User.spec.ts similarity index 100% rename from backend/src/models/User.spec.js rename to backend/src/models/User.spec.ts diff --git a/backend/src/models/User.js b/backend/src/models/User.ts similarity index 100% rename from backend/src/models/User.js rename to backend/src/models/User.ts diff --git a/backend/src/models/index.js b/backend/src/models/index.js deleted file mode 100644 index d476e5f9b..000000000 --- a/backend/src/models/index.js +++ /dev/null @@ -1,20 +0,0 @@ -// NOTE: We cannot use `fs` here to clean up the code. Cypress breaks on any npm -// module that is not browser-compatible. Node's `fs` module is server-side only -export default { - Image: require('./Image.js').default, - Badge: require('./Badge.js').default, - User: require('./User.js').default, - Group: require('./Group.js').default, - EmailAddress: require('./EmailAddress.js').default, - UnverifiedEmailAddress: require('./UnverifiedEmailAddress.js').default, - SocialMedia: require('./SocialMedia.js').default, - Post: require('./Post.js').default, - Comment: require('./Comment.js').default, - Category: require('./Category.js').default, - Tag: require('./Tag.js').default, - Location: require('./Location.js').default, - Donations: require('./Donations.js').default, - Report: require('./Report.js').default, - Migration: require('./Migration.js').default, - InviteCode: require('./InviteCode.js').default, -} diff --git a/backend/src/models/index.ts b/backend/src/models/index.ts new file mode 100644 index 000000000..c75ad31ef --- /dev/null +++ b/backend/src/models/index.ts @@ -0,0 +1,38 @@ +// NOTE: We cannot use `fs` here to clean up the code. Cypress breaks on any npm +// module that is not browser-compatible. Node's `fs` module is server-side only +declare var Cypress: any | undefined +export default { + Image: typeof Cypress !== 'undefined' ? require('./Image') : require('./Image').default, + Badge: typeof Cypress !== 'undefined' ? require('./Badge') : require('./Badge').default, + User: typeof Cypress !== 'undefined' ? require('./User') : require('./User').default, + Group: typeof Cypress !== 'undefined' ? require('./Group') : require('./Group').default, + EmailAddress: + typeof Cypress !== 'undefined' + ? require('./EmailAddress') + : require('./EmailAddress').default, + UnverifiedEmailAddress: + typeof Cypress !== 'undefined' + ? require('./UnverifiedEmailAddress') + : require('./UnverifiedEmailAddress').default, + SocialMedia: + typeof Cypress !== 'undefined' + ? require('./SocialMedia') + : require('./SocialMedia').default, + Post: typeof Cypress !== 'undefined' ? require('./Post') : require('./Post').default, + Comment: + typeof Cypress !== 'undefined' ? require('./Comment') : require('./Comment').default, + Category: + typeof Cypress !== 'undefined' ? require('./Category') : require('./Category').default, + Tag: typeof Cypress !== 'undefined' ? require('./Tag') : require('./Tag').default, + Location: + typeof Cypress !== 'undefined' ? require('./Location') : require('./Location').default, + Donations: + typeof Cypress !== 'undefined' ? require('./Donations') : require('./Donations').default, + Report: typeof Cypress !== 'undefined' ? require('./Report') : require('./Report').default, + Migration: + typeof Cypress !== 'undefined' ? require('./Migration') : require('./Migration').default, + InviteCode: + typeof Cypress !== 'undefined' + ? require('./InviteCode') + : require('./InviteCode').default, +} diff --git a/backend/src/schema/index.js b/backend/src/schema/index.ts similarity index 100% rename from backend/src/schema/index.js rename to backend/src/schema/index.ts diff --git a/backend/src/schema/resolvers/Upload.js b/backend/src/schema/resolvers/Upload.ts similarity index 100% rename from backend/src/schema/resolvers/Upload.js rename to backend/src/schema/resolvers/Upload.ts diff --git a/backend/src/schema/resolvers/badges.js b/backend/src/schema/resolvers/badges.ts similarity index 100% rename from backend/src/schema/resolvers/badges.js rename to backend/src/schema/resolvers/badges.ts diff --git a/backend/src/schema/resolvers/comments.spec.js b/backend/src/schema/resolvers/comments.spec.ts similarity index 100% rename from backend/src/schema/resolvers/comments.spec.js rename to backend/src/schema/resolvers/comments.spec.ts diff --git a/backend/src/schema/resolvers/comments.js b/backend/src/schema/resolvers/comments.ts similarity index 100% rename from backend/src/schema/resolvers/comments.js rename to backend/src/schema/resolvers/comments.ts diff --git a/backend/src/schema/resolvers/donations.spec.js b/backend/src/schema/resolvers/donations.spec.ts similarity index 100% rename from backend/src/schema/resolvers/donations.spec.js rename to backend/src/schema/resolvers/donations.spec.ts diff --git a/backend/src/schema/resolvers/donations.js b/backend/src/schema/resolvers/donations.ts similarity index 100% rename from backend/src/schema/resolvers/donations.js rename to backend/src/schema/resolvers/donations.ts diff --git a/backend/src/schema/resolvers/emails.spec.js b/backend/src/schema/resolvers/emails.spec.ts similarity index 100% rename from backend/src/schema/resolvers/emails.spec.js rename to backend/src/schema/resolvers/emails.spec.ts diff --git a/backend/src/schema/resolvers/emails.js b/backend/src/schema/resolvers/emails.ts similarity index 100% rename from backend/src/schema/resolvers/emails.js rename to backend/src/schema/resolvers/emails.ts diff --git a/backend/src/schema/resolvers/embeds.spec.js b/backend/src/schema/resolvers/embeds.spec.ts similarity index 94% rename from backend/src/schema/resolvers/embeds.spec.js rename to backend/src/schema/resolvers/embeds.spec.ts index b22927d1b..8e7a69891 100644 --- a/backend/src/schema/resolvers/embeds.spec.js +++ b/backend/src/schema/resolvers/embeds.spec.ts @@ -6,10 +6,11 @@ import createServer from '../../server' import gql from 'graphql-tag' jest.mock('node-fetch') +const mockedFetch = jest.mocked(fetch) const { Response } = jest.requireActual('node-fetch') afterEach(() => { - fetch.mockRestore() + mockedFetch.mockRestore() }) let variables = {} @@ -80,9 +81,9 @@ describe('Query', () => { describe('given a video link', () => { beforeEach(() => { - fetch + mockedFetch .mockReturnValueOnce(Promise.resolve(new Response(''))) - .mockReturnValueOnce(Promise.resolve(JSON.stringify({}))) + .mockReturnValueOnce(Promise.resolve(new Response(JSON.stringify({})))) variables = { url: 'https://www.w3schools.com/html/mov_bbb.mp4' } }) @@ -112,9 +113,9 @@ describe('Query', () => { describe('given a Facebook link', () => { beforeEach(() => { - fetch + mockedFetch .mockReturnValueOnce(Promise.resolve(new Response(HumanConnectionOrg))) - .mockReturnValueOnce(Promise.resolve('invalid json')) + .mockReturnValueOnce(Promise.resolve(new Response('invalid json'))) variables = { url: 'https://www.facebook.com/HumanConnectionOrg/' } }) @@ -146,9 +147,9 @@ describe('Query', () => { describe('given a Github link', () => { beforeEach(() => { - fetch + mockedFetch .mockReturnValueOnce(Promise.resolve(new Response(pr3934))) - .mockReturnValueOnce(Promise.resolve(JSON.stringify({}))) + .mockReturnValueOnce(Promise.resolve(new Response(JSON.stringify({})))) variables = { url: 'https://github.com/Human-Connection/Human-Connection/pull/960' } }) @@ -180,7 +181,7 @@ Have all the information for the brand in separate config files. Set these defau describe('given a youtube link', () => { beforeEach(() => { - fetch + mockedFetch .mockReturnValueOnce(Promise.resolve(new Response(babyLovesCat))) .mockReturnValueOnce(Promise.resolve(babyLovesCatEmbedResponse)) variables = { url: 'https://www.youtube.com/watch?v=qkdXAtO40Fo&t=18s' } diff --git a/backend/src/schema/resolvers/embeds.js b/backend/src/schema/resolvers/embeds.ts similarity index 93% rename from backend/src/schema/resolvers/embeds.js rename to backend/src/schema/resolvers/embeds.ts index 016352950..a75365ec7 100644 --- a/backend/src/schema/resolvers/embeds.js +++ b/backend/src/schema/resolvers/embeds.ts @@ -1,4 +1,4 @@ -import scrape from './embeds/scraper.js' +import scrape from './embeds/scraper' import { undefinedToNullResolver } from './helpers/Resolver' export default { diff --git a/backend/src/schema/resolvers/embeds/findProvider.spec.js b/backend/src/schema/resolvers/embeds/findProvider.spec.ts similarity index 100% rename from backend/src/schema/resolvers/embeds/findProvider.spec.js rename to backend/src/schema/resolvers/embeds/findProvider.spec.ts diff --git a/backend/src/schema/resolvers/embeds/findProvider.js b/backend/src/schema/resolvers/embeds/findProvider.ts similarity index 100% rename from backend/src/schema/resolvers/embeds/findProvider.js rename to backend/src/schema/resolvers/embeds/findProvider.ts diff --git a/backend/src/schema/resolvers/embeds/scraper.js b/backend/src/schema/resolvers/embeds/scraper.ts similarity index 100% rename from backend/src/schema/resolvers/embeds/scraper.js rename to backend/src/schema/resolvers/embeds/scraper.ts diff --git a/backend/src/schema/resolvers/filter-posts.spec.js b/backend/src/schema/resolvers/filter-posts.spec.ts similarity index 98% rename from backend/src/schema/resolvers/filter-posts.spec.js rename to backend/src/schema/resolvers/filter-posts.spec.ts index 0b96e001f..41fbd0ea7 100644 --- a/backend/src/schema/resolvers/filter-posts.spec.js +++ b/backend/src/schema/resolvers/filter-posts.spec.ts @@ -158,7 +158,7 @@ describe('Filter Posts', () => { }) describe('order events by event start descending', () => { - it('finds the events orderd accordingly', async () => { + it('finds the events ordered accordingly', async () => { const { data: { Post: result }, } = await query({ @@ -180,7 +180,7 @@ describe('Filter Posts', () => { }) describe('order events by event start ascending', () => { - it('finds the events orderd accordingly', async () => { + it('finds the events ordered accordingly', async () => { const { data: { Post: result }, } = await query({ diff --git a/backend/src/schema/resolvers/follow.spec.js b/backend/src/schema/resolvers/follow.spec.ts similarity index 100% rename from backend/src/schema/resolvers/follow.spec.js rename to backend/src/schema/resolvers/follow.spec.ts diff --git a/backend/src/schema/resolvers/follow.js b/backend/src/schema/resolvers/follow.ts similarity index 100% rename from backend/src/schema/resolvers/follow.js rename to backend/src/schema/resolvers/follow.ts diff --git a/backend/src/schema/resolvers/groups.spec.js b/backend/src/schema/resolvers/groups.spec.ts similarity index 95% rename from backend/src/schema/resolvers/groups.spec.js rename to backend/src/schema/resolvers/groups.spec.ts index 13291383d..315388490 100644 --- a/backend/src/schema/resolvers/groups.spec.js +++ b/backend/src/schema/resolvers/groups.spec.ts @@ -270,7 +270,7 @@ describe('in mode', () => { describe('unauthenticated', () => { it('throws authorization error', async () => { const { errors } = await mutate({ mutation: createGroupMutation(), variables }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -339,7 +339,7 @@ describe('in mode', () => { '0123456789', }, }) - expect(errors[0]).toHaveProperty('message', 'Description too short!') + expect(errors![0]).toHaveProperty('message', 'Description too short!') }) }) }) @@ -382,7 +382,7 @@ describe('in mode', () => { mutation: createGroupMutation(), variables: { ...variables, categoryIds: null }, }) - expect(errors[0]).toHaveProperty('message', 'Too view categories!') + expect(errors![0]).toHaveProperty('message', 'Too view categories!') }) }) @@ -392,7 +392,7 @@ describe('in mode', () => { mutation: createGroupMutation(), variables: { ...variables, categoryIds: [] }, }) - expect(errors[0]).toHaveProperty('message', 'Too view categories!') + expect(errors![0]).toHaveProperty('message', 'Too view categories!') }) }) }) @@ -403,7 +403,7 @@ describe('in mode', () => { mutation: createGroupMutation(), variables: { ...variables, categoryIds: ['cat9', 'cat4', 'cat15', 'cat27'] }, }) - expect(errors[0]).toHaveProperty('message', 'Too many categories!') + expect(errors![0]).toHaveProperty('message', 'Too many categories!') }) }) }) @@ -424,7 +424,7 @@ describe('in mode', () => { describe('unauthenticated', () => { it('throws authorization error', async () => { const { errors } = await query({ query: groupQuery(), variables: {} }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -577,7 +577,7 @@ describe('in mode', () => { }, errors: undefined, }) - expect(result.data.Group.length).toBe(3) + expect(result.data?.Group.length).toBe(3) }) describe('categories', () => { @@ -635,7 +635,7 @@ describe('in mode', () => { }, errors: undefined, }) - expect(result.data.Group.length).toBe(1) + expect(result.data?.Group.length).toBe(1) }) }) @@ -657,7 +657,7 @@ describe('in mode', () => { }, errors: undefined, }) - expect(result.data.Group.length).toBe(1) + expect(result.data?.Group.length).toBe(1) }) }) @@ -667,7 +667,7 @@ describe('in mode', () => { query: groupQuery(), variables: { id: 'second-hidden-group' }, }) - expect(result.data.Group.length).toBe(0) + expect(result.data?.Group.length).toBe(0) }) }) @@ -677,7 +677,7 @@ describe('in mode', () => { query: groupQuery(), variables: { id: 'hidden-group' }, }) - expect(result.data.Group.length).toBe(0) + expect(result.data?.Group.length).toBe(0) }) }) }) @@ -701,7 +701,7 @@ describe('in mode', () => { }, errors: undefined, }) - expect(result.data.Group.length).toBe(1) + expect(result.data?.Group.length).toBe(1) }) }) @@ -723,7 +723,7 @@ describe('in mode', () => { }, errors: undefined, }) - expect(result.data.Group.length).toBe(1) + expect(result.data?.Group.length).toBe(1) }) }) @@ -733,7 +733,7 @@ describe('in mode', () => { query: groupQuery(), variables: { slug: 'second-investigative-journalism-group' }, }) - expect(result.data.Group.length).toBe(0) + expect(result.data?.Group.length).toBe(0) }) }) @@ -743,7 +743,7 @@ describe('in mode', () => { query: groupQuery(), variables: { slug: 'investigative-journalism-group' }, }) - expect(result.data.Group.length).toBe(0) + expect(result.data?.Group.length).toBe(0) }) }) }) @@ -768,7 +768,7 @@ describe('in mode', () => { }, errors: undefined, }) - expect(result.data.Group.length).toBe(2) + expect(result.data?.Group.length).toBe(2) }) }) @@ -787,7 +787,7 @@ describe('in mode', () => { }, errors: undefined, }) - expect(result.data.Group.length).toBe(1) + expect(result.data?.Group.length).toBe(1) }) }) }) @@ -813,7 +813,7 @@ describe('in mode', () => { userId: 'current-user', }, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -994,7 +994,7 @@ describe('in mode', () => { userId: 'owner-of-closed-group', }, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -1040,7 +1040,7 @@ describe('in mode', () => { id: 'not-existing-group', } const { errors } = await query({ query: groupMembersQuery(), variables }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -1234,7 +1234,7 @@ describe('in mode', () => { }, errors: undefined, }) - expect(result.data.GroupMembers.length).toBe(3) + expect(result.data?.GroupMembers.length).toBe(3) }) }) @@ -1267,7 +1267,7 @@ describe('in mode', () => { }, errors: undefined, }) - expect(result.data.GroupMembers.length).toBe(3) + expect(result.data?.GroupMembers.length).toBe(3) }) }) @@ -1300,7 +1300,7 @@ describe('in mode', () => { }, errors: undefined, }) - expect(result.data.GroupMembers.length).toBe(3) + expect(result.data?.GroupMembers.length).toBe(3) }) }) }) @@ -1343,7 +1343,7 @@ describe('in mode', () => { }, errors: undefined, }) - expect(result.data.GroupMembers.length).toBe(3) + expect(result.data?.GroupMembers.length).toBe(3) }) }) @@ -1376,7 +1376,7 @@ describe('in mode', () => { }, errors: undefined, }) - expect(result.data.GroupMembers.length).toBe(3) + expect(result.data?.GroupMembers.length).toBe(3) }) }) @@ -1387,7 +1387,7 @@ describe('in mode', () => { it('throws authorization error', async () => { const { errors } = await query({ query: groupMembersQuery(), variables }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -1398,7 +1398,7 @@ describe('in mode', () => { it('throws authorization error', async () => { const { errors } = await query({ query: groupMembersQuery(), variables }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -1445,7 +1445,7 @@ describe('in mode', () => { }, errors: undefined, }) - expect(result.data.GroupMembers.length).toBe(4) + expect(result.data?.GroupMembers.length).toBe(4) }) }) @@ -1482,7 +1482,7 @@ describe('in mode', () => { }, errors: undefined, }) - expect(result.data.GroupMembers.length).toBe(4) + expect(result.data?.GroupMembers.length).toBe(4) }) }) @@ -1519,7 +1519,7 @@ describe('in mode', () => { }, errors: undefined, }) - expect(result.data.GroupMembers.length).toBe(4) + expect(result.data?.GroupMembers.length).toBe(4) }) }) @@ -1530,7 +1530,7 @@ describe('in mode', () => { it('throws authorization error', async () => { const { errors } = await query({ query: groupMembersQuery(), variables }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -1541,7 +1541,7 @@ describe('in mode', () => { it('throws authorization error', async () => { const { errors } = await query({ query: groupMembersQuery(), variables }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -1568,7 +1568,7 @@ describe('in mode', () => { roleInGroup: 'pending', }, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -1723,7 +1723,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -1749,7 +1749,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -1798,7 +1798,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -1821,7 +1821,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -1844,7 +1844,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -1902,7 +1902,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -1925,7 +1925,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -1942,7 +1942,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -1965,7 +1965,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -1982,7 +1982,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -2005,7 +2005,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -2022,7 +2022,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -2112,7 +2112,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -2129,7 +2129,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -2152,7 +2152,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -2169,7 +2169,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -2192,7 +2192,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -2209,7 +2209,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -2299,7 +2299,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -2322,7 +2322,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -2345,7 +2345,7 @@ describe('in mode', () => { mutation: changeGroupMemberRoleMutation(), variables, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -2409,7 +2409,7 @@ describe('in mode', () => { userId: 'current-user', }, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -2526,7 +2526,7 @@ describe('in mode', () => { userId: 'owner-member-user', }, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -2540,7 +2540,7 @@ describe('in mode', () => { userId: 'second-owner-member-user', }, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -2554,7 +2554,7 @@ describe('in mode', () => { userId: 'none-member-user', }, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -2568,7 +2568,7 @@ describe('in mode', () => { userId: 'usual-member-user', }, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -2582,7 +2582,7 @@ describe('in mode', () => { userId: 'admin-member-user', }, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) @@ -2608,7 +2608,7 @@ describe('in mode', () => { slug: 'my-best-group', }, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -2861,7 +2861,7 @@ describe('in mode', () => { '0123456789', }, }) - expect(errors[0]).toHaveProperty('message', 'Description too short!') + expect(errors![0]).toHaveProperty('message', 'Description too short!') }) }) }) @@ -2908,7 +2908,7 @@ describe('in mode', () => { categoryIds: [], }, }) - expect(errors[0]).toHaveProperty('message', 'Too view categories!') + expect(errors![0]).toHaveProperty('message', 'Too view categories!') }) }) }) @@ -2922,7 +2922,7 @@ describe('in mode', () => { categoryIds: ['cat9', 'cat4', 'cat15', 'cat27'], }, }) - expect(errors[0]).toHaveProperty('message', 'Too many categories!') + expect(errors![0]).toHaveProperty('message', 'Too many categories!') }) }) }) @@ -2942,7 +2942,7 @@ describe('in mode', () => { categoryIds: ['cat4', 'cat27'], }, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) @@ -2960,7 +2960,7 @@ describe('in mode', () => { categoryIds: ['cat4', 'cat27'], }, }) - expect(errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(errors![0]).toHaveProperty('message', 'Not Authorized!') }) }) }) diff --git a/backend/src/schema/resolvers/groups.js b/backend/src/schema/resolvers/groups.ts similarity index 99% rename from backend/src/schema/resolvers/groups.js rename to backend/src/schema/resolvers/groups.ts index 5ec1700b9..cd1eb8db3 100644 --- a/backend/src/schema/resolvers/groups.js +++ b/backend/src/schema/resolvers/groups.ts @@ -3,7 +3,7 @@ import { UserInputError } from 'apollo-server' import CONFIG from '../../config' import { CATEGORIES_MIN, CATEGORIES_MAX } from '../../constants/categories' import { DESCRIPTION_WITHOUT_HTML_LENGTH_MIN } from '../../constants/groups' -import { removeHtmlTags } from '../../middleware/helpers/cleanHtml.js' +import { removeHtmlTags } from '../../middleware/helpers/cleanHtml' import Resolver, { removeUndefinedNullValuesFromObject, convertObjectToCypherMapLiteral, diff --git a/backend/src/schema/resolvers/helpers/Resolver.js b/backend/src/schema/resolvers/helpers/Resolver.ts similarity index 97% rename from backend/src/schema/resolvers/helpers/Resolver.js rename to backend/src/schema/resolvers/helpers/Resolver.ts index 6e8211521..58d1512d7 100644 --- a/backend/src/schema/resolvers/helpers/Resolver.js +++ b/backend/src/schema/resolvers/helpers/Resolver.ts @@ -10,7 +10,7 @@ export const undefinedToNullResolver = (list) => { return resolvers } -export default function Resolver(type, options = {}) { +export default function Resolver(type, options: any = {}) { const { idAttribute = 'id', undefinedToNull = [], @@ -44,7 +44,7 @@ export default function Resolver(type, options = {}) { } } - const booleanResolver = (obj) => { + const booleanResolver = (obj: any[]) => { const resolvers = {} for (const [key, condition] of Object.entries(obj)) { resolvers[key] = async (parent, params, { cypherParams, driver }, resolveInfo) => { diff --git a/backend/src/schema/resolvers/helpers/createPasswordReset.js b/backend/src/schema/resolvers/helpers/createPasswordReset.ts similarity index 100% rename from backend/src/schema/resolvers/helpers/createPasswordReset.js rename to backend/src/schema/resolvers/helpers/createPasswordReset.ts diff --git a/backend/src/schema/resolvers/helpers/databaseLogger.js b/backend/src/schema/resolvers/helpers/databaseLogger.ts similarity index 100% rename from backend/src/schema/resolvers/helpers/databaseLogger.js rename to backend/src/schema/resolvers/helpers/databaseLogger.ts diff --git a/backend/src/schema/resolvers/helpers/events.js b/backend/src/schema/resolvers/helpers/events.ts similarity index 82% rename from backend/src/schema/resolvers/helpers/events.js rename to backend/src/schema/resolvers/helpers/events.ts index 84e64299d..835088d8c 100644 --- a/backend/src/schema/resolvers/helpers/events.js +++ b/backend/src/schema/resolvers/helpers/events.ts @@ -1,29 +1,32 @@ import { UserInputError } from 'apollo-server' export const validateEventParams = (params) => { + let locationName = null if (params.postType && params.postType === 'Event') { const { eventInput } = params validateEventDate(eventInput.eventStart) params.eventStart = eventInput.eventStart + if (eventInput.eventEnd) { validateEventEnd(eventInput.eventStart, eventInput.eventEnd) params.eventEnd = eventInput.eventEnd + } else { + params.eventEnd = null } + if (eventInput.eventLocationName && !eventInput.eventVenue) { throw new UserInputError('Event venue must be present if event location is given!') } params.eventVenue = eventInput.eventVenue - params.eventLocationName = eventInput.eventLocationName + params.eventLocationName = eventInput.eventLocationName && eventInput.eventLocationName.trim() + if (params.eventLocationName) { + locationName = params.eventLocationName + } else { + params.eventLocationName = null + } params.eventIsOnline = !!eventInput.eventIsOnline } delete params.eventInput - let locationName - if (params.eventLocationName) { - locationName = params.eventLocationName - } else { - params.eventLocationName = null - locationName = null - } return locationName } diff --git a/backend/src/schema/resolvers/helpers/existingEmailAddress.js b/backend/src/schema/resolvers/helpers/existingEmailAddress.ts similarity index 100% rename from backend/src/schema/resolvers/helpers/existingEmailAddress.js rename to backend/src/schema/resolvers/helpers/existingEmailAddress.ts diff --git a/backend/src/schema/resolvers/helpers/filterForMutedUsers.js b/backend/src/schema/resolvers/helpers/filterForMutedUsers.ts similarity index 92% rename from backend/src/schema/resolvers/helpers/filterForMutedUsers.js rename to backend/src/schema/resolvers/helpers/filterForMutedUsers.ts index 5094039ee..1d1369e0d 100644 --- a/backend/src/schema/resolvers/helpers/filterForMutedUsers.js +++ b/backend/src/schema/resolvers/helpers/filterForMutedUsers.ts @@ -1,4 +1,4 @@ -import { getMutedUsers } from '../users.js' +import { getMutedUsers } from '../users' import { mergeWith, isArray } from 'lodash' export const filterForMutedUsers = async (params, context) => { diff --git a/backend/src/schema/resolvers/helpers/filterInvisiblePosts.js b/backend/src/schema/resolvers/helpers/filterInvisiblePosts.ts similarity index 100% rename from backend/src/schema/resolvers/helpers/filterInvisiblePosts.js rename to backend/src/schema/resolvers/helpers/filterInvisiblePosts.ts diff --git a/backend/src/schema/resolvers/helpers/filterPostsOfMyGroups.js b/backend/src/schema/resolvers/helpers/filterPostsOfMyGroups.ts similarity index 100% rename from backend/src/schema/resolvers/helpers/filterPostsOfMyGroups.js rename to backend/src/schema/resolvers/helpers/filterPostsOfMyGroups.ts diff --git a/backend/src/schema/resolvers/helpers/generateInviteCode.js b/backend/src/schema/resolvers/helpers/generateInviteCode.ts similarity index 89% rename from backend/src/schema/resolvers/helpers/generateInviteCode.js rename to backend/src/schema/resolvers/helpers/generateInviteCode.ts index 99c752eb0..5a123ff88 100644 --- a/backend/src/schema/resolvers/helpers/generateInviteCode.js +++ b/backend/src/schema/resolvers/helpers/generateInviteCode.ts @@ -4,7 +4,7 @@ export default function generateInviteCode() { // 6 random numbers in [ 0, 35 ] are 36 possible numbers (10 [0-9] + 26 [A-Z]) return Array.from( { length: CONSTANTS_REGISTRATION.INVITE_CODE_LENGTH }, - (n = Math.floor(Math.random() * 36)) => { + (n: number = Math.floor(Math.random() * 36)) => { // n > 9: it is a letter (ASCII 65 is A) -> 10 + 55 = 65 // else: it is a number (ASCII 48 is 0) -> 0 + 48 = 48 return String.fromCharCode(n > 9 ? n + 55 : n + 48) diff --git a/backend/src/schema/resolvers/helpers/generateNonce.js b/backend/src/schema/resolvers/helpers/generateNonce.ts similarity index 85% rename from backend/src/schema/resolvers/helpers/generateNonce.js rename to backend/src/schema/resolvers/helpers/generateNonce.ts index 50aa8489e..f08b3ccd6 100644 --- a/backend/src/schema/resolvers/helpers/generateNonce.js +++ b/backend/src/schema/resolvers/helpers/generateNonce.ts @@ -4,7 +4,7 @@ import CONSTANTS_REGISTRATION from './../../../constants/registration' export default function generateNonce() { return Array.from( { length: CONSTANTS_REGISTRATION.NONCE_LENGTH }, - (n = Math.floor(Math.random() * 10)) => { + (n: number = Math.floor(Math.random() * 10)) => { return String.fromCharCode(n + 48) }, ).join('') diff --git a/backend/src/schema/resolvers/helpers/normalizeEmail.js b/backend/src/schema/resolvers/helpers/normalizeEmail.ts similarity index 100% rename from backend/src/schema/resolvers/helpers/normalizeEmail.js rename to backend/src/schema/resolvers/helpers/normalizeEmail.ts diff --git a/backend/src/schema/resolvers/images.js b/backend/src/schema/resolvers/images.ts similarity index 100% rename from backend/src/schema/resolvers/images.js rename to backend/src/schema/resolvers/images.ts diff --git a/backend/src/schema/resolvers/images/images.spec.js b/backend/src/schema/resolvers/images/images.spec.ts similarity index 100% rename from backend/src/schema/resolvers/images/images.spec.js rename to backend/src/schema/resolvers/images/images.spec.ts diff --git a/backend/src/schema/resolvers/images/images.js b/backend/src/schema/resolvers/images/images.ts similarity index 99% rename from backend/src/schema/resolvers/images/images.js rename to backend/src/schema/resolvers/images/images.ts index 180c6d090..b99b13a10 100644 --- a/backend/src/schema/resolvers/images/images.js +++ b/backend/src/schema/resolvers/images/images.ts @@ -10,7 +10,7 @@ import CONFIG from '../../../config' // const widths = [34, 160, 320, 640, 1024] const { AWS_ENDPOINT: endpoint, AWS_REGION: region, AWS_BUCKET: Bucket, S3_CONFIGURED } = CONFIG -export async function deleteImage(resource, relationshipType, opts = {}) { +export async function deleteImage(resource, relationshipType, opts: any = {}) { sanitizeRelationshipType(relationshipType) const { transaction, deleteCallback } = opts if (!transaction) return wrapTransaction(deleteImage, [resource, relationshipType], opts) @@ -32,7 +32,7 @@ export async function deleteImage(resource, relationshipType, opts = {}) { return image } -export async function mergeImage(resource, relationshipType, imageInput, opts = {}) { +export async function mergeImage(resource, relationshipType, imageInput, opts: any = {}) { if (typeof imageInput === 'undefined') return if (imageInput === null) return deleteImage(resource, relationshipType, opts) sanitizeRelationshipType(relationshipType) diff --git a/backend/src/schema/resolvers/index.js b/backend/src/schema/resolvers/index.ts similarity index 63% rename from backend/src/schema/resolvers/index.js rename to backend/src/schema/resolvers/index.ts index 3d3a91d68..1aeadbea2 100644 --- a/backend/src/schema/resolvers/index.js +++ b/backend/src/schema/resolvers/index.ts @@ -1,5 +1,6 @@ import path from 'path' import { fileLoader, mergeResolvers } from 'merge-graphql-schemas' -const resolversArray = fileLoader(path.join(__dirname, './!(*.spec).js')) +// the files must be correctly evaluated in built and dev state - therefore accept both js & ts files +const resolversArray = fileLoader(path.join(__dirname, './!(*.spec).(ts|js)')) export default mergeResolvers(resolversArray) diff --git a/backend/src/schema/resolvers/inviteCodes.spec.js b/backend/src/schema/resolvers/inviteCodes.spec.ts similarity index 100% rename from backend/src/schema/resolvers/inviteCodes.spec.js rename to backend/src/schema/resolvers/inviteCodes.spec.ts diff --git a/backend/src/schema/resolvers/inviteCodes.js b/backend/src/schema/resolvers/inviteCodes.ts similarity index 100% rename from backend/src/schema/resolvers/inviteCodes.js rename to backend/src/schema/resolvers/inviteCodes.ts diff --git a/backend/src/schema/resolvers/locations.spec.js b/backend/src/schema/resolvers/locations.spec.ts similarity index 100% rename from backend/src/schema/resolvers/locations.spec.js rename to backend/src/schema/resolvers/locations.spec.ts diff --git a/backend/src/schema/resolvers/locations.js b/backend/src/schema/resolvers/locations.ts similarity index 100% rename from backend/src/schema/resolvers/locations.js rename to backend/src/schema/resolvers/locations.ts diff --git a/backend/src/schema/resolvers/moderation.spec.js b/backend/src/schema/resolvers/moderation.spec.ts similarity index 100% rename from backend/src/schema/resolvers/moderation.spec.js rename to backend/src/schema/resolvers/moderation.spec.ts diff --git a/backend/src/schema/resolvers/moderation.js b/backend/src/schema/resolvers/moderation.ts similarity index 91% rename from backend/src/schema/resolvers/moderation.js rename to backend/src/schema/resolvers/moderation.ts index 97f48ec43..4906aea90 100644 --- a/backend/src/schema/resolvers/moderation.js +++ b/backend/src/schema/resolvers/moderation.ts @@ -18,7 +18,7 @@ export default { SET report.updatedAt = $dateTime, report.disable = review.disable, report.closed = $params.closed SET resource.disabled = report.disable - WITH review, report, resource {.*, __typename: labels(resource)[0]} AS finalResource + WITH review, report, resource {.*, __typename: filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'User'])[0]} AS finalResource RETURN review {.*, report: properties(report), resource: properties(finalResource)} ` const reviewWriteTxResultPromise = session.writeTransaction(async (txc) => { diff --git a/backend/src/schema/resolvers/notifications.spec.js b/backend/src/schema/resolvers/notifications.spec.ts similarity index 100% rename from backend/src/schema/resolvers/notifications.spec.js rename to backend/src/schema/resolvers/notifications.spec.ts diff --git a/backend/src/schema/resolvers/notifications.js b/backend/src/schema/resolvers/notifications.ts similarity index 92% rename from backend/src/schema/resolvers/notifications.js rename to backend/src/schema/resolvers/notifications.ts index c3b882146..83c4da11b 100644 --- a/backend/src/schema/resolvers/notifications.js +++ b/backend/src/schema/resolvers/notifications.ts @@ -54,7 +54,7 @@ export default { [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post {.*, author: properties(author), postType: filter(l IN labels(post) WHERE NOT l = "Post")} ] AS posts WITH resource, user, notification, authors, posts, relatedUser, membership, resource {.*, - __typename: labels(resource)[0], + __typename: filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'Group'])[0], author: authors[0], post: posts[0], myRole: membership.role } AS finalResource @@ -93,7 +93,7 @@ export default { [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author), postType: filter(l IN labels(post) WHERE NOT l = "Post")} ] AS posts OPTIONAL MATCH (resource)<-[membership:MEMBER_OF]-(user) WITH resource, user, notification, authors, posts, membership, - resource {.*, __typename: labels(resource)[0], author: authors[0], post: posts[0], myRole: membership.role } AS finalResource + resource {.*, __typename: filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'Group'])[0], author: authors[0], post: posts[0], myRole: membership.role } AS finalResource RETURN notification {.*, from: finalResource, to: properties(user)} `, { resourceId: args.id, id: currentUser.id }, @@ -123,7 +123,7 @@ export default { [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author), postType: filter(l IN labels(post) WHERE NOT l = "Post")} ] AS posts OPTIONAL MATCH (resource)<-[membership:MEMBER_OF]-(user) WITH resource, user, notification, authors, posts, membership, - resource {.*, __typename: labels(resource)[0], author: authors[0], post: posts[0], myRole: membership.role} AS finalResource + resource {.*, __typename: filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'Group'])[0], author: authors[0], post: posts[0], myRole: membership.role} AS finalResource RETURN notification {.*, from: finalResource, to: properties(user)} `, { id: currentUser.id }, diff --git a/backend/src/schema/resolvers/passwordReset.spec.js b/backend/src/schema/resolvers/passwordReset.spec.ts similarity index 99% rename from backend/src/schema/resolvers/passwordReset.spec.js rename to backend/src/schema/resolvers/passwordReset.spec.ts index fa5f26e58..3d17ff481 100644 --- a/backend/src/schema/resolvers/passwordReset.spec.js +++ b/backend/src/schema/resolvers/passwordReset.spec.ts @@ -119,7 +119,7 @@ describe('passwordReset', () => { }) describe('resetPassword', () => { - const setup = async (options = {}) => { + const setup = async (options: any = {}) => { const { email = 'user@example.org', issuedAt = new Date(), nonce = '12345' } = options await createPasswordReset({ driver, email, issuedAt, nonce }) } diff --git a/backend/src/schema/resolvers/passwordReset.js b/backend/src/schema/resolvers/passwordReset.ts similarity index 100% rename from backend/src/schema/resolvers/passwordReset.js rename to backend/src/schema/resolvers/passwordReset.ts diff --git a/backend/src/schema/resolvers/posts.spec.js b/backend/src/schema/resolvers/posts.spec.ts similarity index 100% rename from backend/src/schema/resolvers/posts.spec.js rename to backend/src/schema/resolvers/posts.spec.ts diff --git a/backend/src/schema/resolvers/posts.js b/backend/src/schema/resolvers/posts.ts similarity index 98% rename from backend/src/schema/resolvers/posts.js rename to backend/src/schema/resolvers/posts.ts index c7d2eebdb..c9bfca053 100644 --- a/backend/src/schema/resolvers/posts.js +++ b/backend/src/schema/resolvers/posts.ts @@ -21,12 +21,22 @@ const maintainPinnedPosts = (params) => { return params } +const filterEventDates = (params) => { + if (params.filter?.eventStart_gte) { + const date = params.filter.eventStart_gte + delete params.filter.eventStart_gte + params.filter = { ...params.filter, OR: [{ eventStart_gte: date }, { eventEnd_gte: date }] } + } + return params +} + export default { Query: { Post: async (object, params, context, resolveInfo) => { params = await filterPostsOfMyGroups(params, context) params = await filterInvisiblePosts(params, context) params = await filterForMutedUsers(params, context) + params = filterEventDates(params) params = await maintainPinnedPosts(params) return neo4jgraphql(object, params, context, resolveInfo) }, diff --git a/backend/src/schema/resolvers/postsInGroups.spec.js b/backend/src/schema/resolvers/postsInGroups.spec.ts similarity index 100% rename from backend/src/schema/resolvers/postsInGroups.spec.js rename to backend/src/schema/resolvers/postsInGroups.spec.ts diff --git a/backend/src/schema/resolvers/registration.spec.js b/backend/src/schema/resolvers/registration.spec.ts similarity index 100% rename from backend/src/schema/resolvers/registration.spec.js rename to backend/src/schema/resolvers/registration.spec.ts diff --git a/backend/src/schema/resolvers/registration.js b/backend/src/schema/resolvers/registration.ts similarity index 100% rename from backend/src/schema/resolvers/registration.js rename to backend/src/schema/resolvers/registration.ts diff --git a/backend/src/schema/resolvers/reports.spec.js b/backend/src/schema/resolvers/reports.spec.ts similarity index 100% rename from backend/src/schema/resolvers/reports.spec.js rename to backend/src/schema/resolvers/reports.spec.ts diff --git a/backend/src/schema/resolvers/reports.js b/backend/src/schema/resolvers/reports.ts similarity index 93% rename from backend/src/schema/resolvers/reports.js rename to backend/src/schema/resolvers/reports.ts index da61e6f10..a09f52816 100644 --- a/backend/src/schema/resolvers/reports.js +++ b/backend/src/schema/resolvers/reports.ts @@ -17,7 +17,7 @@ export default { WITH submitter, resource, report CREATE (report)<-[filed:FILED {createdAt: $createdAt, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription}]-(submitter) - WITH filed, report, resource {.*, __typename: labels(resource)[0]} AS finalResource + WITH filed, report, resource {.*, __typename: filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'User'])[0]} AS finalResource RETURN filed {.*, reportId: report.id, resource: properties(finalResource)} AS filedReport `, { @@ -92,8 +92,8 @@ export default { [(submitter:User)-[filed:FILED]->(report) | filed {.*, submitter: properties(submitter)} ] as filed, [(moderator:User)-[reviewed:REVIEWED]->(report) | reviewed {.*, moderator: properties(moderator)} ] as reviewed, [(resource)<-[:WROTE]-(author:User) | author {.*} ] as optionalAuthors, - [(resource)-[:COMMENTS]->(post:Post) | post {.*} ] as optionalCommentedPosts, - resource {.*, __typename: labels(resource)[0] } as resourceWithType + [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post {.*, author: properties(author), postType: filter(l IN labels(post) WHERE NOT l = "Post")} ] as optionalCommentedPosts, + resource {.*, __typename: filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'User'])[0] } as resourceWithType WITH report, optionalAuthors, optionalCommentedPosts, reviewed, filed, resourceWithType {.*, post: optionalCommentedPosts[0], author: optionalAuthors[0] } as finalResource RETURN report {.*, resource: finalResource, filed: filed, reviewed: reviewed } @@ -106,7 +106,7 @@ export default { }) try { const reports = await reportsReadTxPromise - return reports + return reports || [] } finally { session.close() } diff --git a/backend/src/schema/resolvers/rewards.spec.js b/backend/src/schema/resolvers/rewards.spec.ts similarity index 100% rename from backend/src/schema/resolvers/rewards.spec.js rename to backend/src/schema/resolvers/rewards.spec.ts diff --git a/backend/src/schema/resolvers/rewards.js b/backend/src/schema/resolvers/rewards.ts similarity index 100% rename from backend/src/schema/resolvers/rewards.js rename to backend/src/schema/resolvers/rewards.ts diff --git a/backend/src/schema/resolvers/roles.js b/backend/src/schema/resolvers/roles.ts similarity index 100% rename from backend/src/schema/resolvers/roles.js rename to backend/src/schema/resolvers/roles.ts diff --git a/backend/src/schema/resolvers/searches.spec.js b/backend/src/schema/resolvers/searches.spec.ts similarity index 100% rename from backend/src/schema/resolvers/searches.spec.js rename to backend/src/schema/resolvers/searches.spec.ts diff --git a/backend/src/schema/resolvers/searches.js b/backend/src/schema/resolvers/searches.ts similarity index 95% rename from backend/src/schema/resolvers/searches.js rename to backend/src/schema/resolvers/searches.ts index 08825fad0..fba74ecc7 100644 --- a/backend/src/schema/resolvers/searches.js +++ b/backend/src/schema/resolvers/searches.ts @@ -38,7 +38,7 @@ const searchPostsSetup = { [(resource)<-[:SHOUTED]-(user:User) | user] AS shouter`, returnClause: `resource { .*, - __typename: labels(resource)[0], + __typename: 'Post', author: properties(author), commentsCount: toString(size(comments)), shoutedCount: toString(size(shouter)), @@ -53,7 +53,7 @@ const searchUsersSetup = { match: 'MATCH (resource:User)', whereClause: simpleWhereClause, withClause: '', - returnClause: 'resource {.*, __typename: labels(resource)[0]}', + returnClause: `resource {.*, __typename: 'User'}`, limit: 'LIMIT toInteger($limit)', } @@ -62,7 +62,7 @@ const searchHashtagsSetup = { match: 'MATCH (resource:Tag)', whereClause: simpleWhereClause, withClause: '', - returnClause: 'resource {.*, __typename: labels(resource)[0]}', + returnClause: `resource {.*, __typename: 'Tag'}`, limit: 'LIMIT toInteger($limit)', } @@ -77,7 +77,7 @@ const searchGroupsSetup = { AND (resource.groupType IN ['public', 'closed'] OR membership.role IN ['usual', 'admin', 'owner'])`, withClause: 'WITH resource, membership', - returnClause: 'resource { .*, myRole: membership.role, __typename: labels(resource)[0] }', + returnClause: `resource { .*, myRole: membership.role, __typename: 'Group' }`, limit: 'LIMIT toInteger($limit)', } @@ -244,7 +244,7 @@ export default { ] params.limit = 15 - const type = multiSearchMap.find((obj) => obj.symbol === searchType) + const type: any = multiSearchMap.find((obj) => obj.symbol === searchType) return getSearchResults(context, type.setup, params) }, }, diff --git a/backend/src/schema/resolvers/searches/queryString.spec.js b/backend/src/schema/resolvers/searches/queryString.spec.ts similarity index 100% rename from backend/src/schema/resolvers/searches/queryString.spec.js rename to backend/src/schema/resolvers/searches/queryString.spec.ts diff --git a/backend/src/schema/resolvers/searches/queryString.js b/backend/src/schema/resolvers/searches/queryString.ts similarity index 100% rename from backend/src/schema/resolvers/searches/queryString.js rename to backend/src/schema/resolvers/searches/queryString.ts diff --git a/backend/src/schema/resolvers/shout.spec.js b/backend/src/schema/resolvers/shout.spec.ts similarity index 100% rename from backend/src/schema/resolvers/shout.spec.js rename to backend/src/schema/resolvers/shout.spec.ts diff --git a/backend/src/schema/resolvers/shout.js b/backend/src/schema/resolvers/shout.ts similarity index 100% rename from backend/src/schema/resolvers/shout.js rename to backend/src/schema/resolvers/shout.ts diff --git a/backend/src/schema/resolvers/socialMedia.spec.js b/backend/src/schema/resolvers/socialMedia.spec.ts similarity index 100% rename from backend/src/schema/resolvers/socialMedia.spec.js rename to backend/src/schema/resolvers/socialMedia.spec.ts diff --git a/backend/src/schema/resolvers/socialMedia.js b/backend/src/schema/resolvers/socialMedia.ts similarity index 100% rename from backend/src/schema/resolvers/socialMedia.js rename to backend/src/schema/resolvers/socialMedia.ts diff --git a/backend/src/schema/resolvers/statistics.spec.js b/backend/src/schema/resolvers/statistics.spec.ts similarity index 100% rename from backend/src/schema/resolvers/statistics.spec.js rename to backend/src/schema/resolvers/statistics.spec.ts diff --git a/backend/src/schema/resolvers/statistics.js b/backend/src/schema/resolvers/statistics.ts similarity index 97% rename from backend/src/schema/resolvers/statistics.js rename to backend/src/schema/resolvers/statistics.ts index d9b7c153e..b454ce8f4 100644 --- a/backend/src/schema/resolvers/statistics.js +++ b/backend/src/schema/resolvers/statistics.ts @@ -4,7 +4,7 @@ export default { Query: { statistics: async (_parent, _args, { driver }) => { const session = driver.session() - const counts = {} + const counts: any = {} try { const mapping = { countUsers: 'User', diff --git a/backend/src/schema/resolvers/transactions/inviteCodes.js b/backend/src/schema/resolvers/transactions/inviteCodes.ts similarity index 100% rename from backend/src/schema/resolvers/transactions/inviteCodes.js rename to backend/src/schema/resolvers/transactions/inviteCodes.ts diff --git a/backend/src/schema/resolvers/userData.spec.js b/backend/src/schema/resolvers/userData.spec.ts similarity index 100% rename from backend/src/schema/resolvers/userData.spec.js rename to backend/src/schema/resolvers/userData.spec.ts diff --git a/backend/src/schema/resolvers/userData.js b/backend/src/schema/resolvers/userData.ts similarity index 100% rename from backend/src/schema/resolvers/userData.js rename to backend/src/schema/resolvers/userData.ts diff --git a/backend/src/schema/resolvers/user_management.spec.js b/backend/src/schema/resolvers/user_management.spec.ts similarity index 100% rename from backend/src/schema/resolvers/user_management.spec.js rename to backend/src/schema/resolvers/user_management.spec.ts diff --git a/backend/src/schema/resolvers/user_management.js b/backend/src/schema/resolvers/user_management.ts similarity index 100% rename from backend/src/schema/resolvers/user_management.js rename to backend/src/schema/resolvers/user_management.ts diff --git a/backend/src/schema/resolvers/users.spec.js b/backend/src/schema/resolvers/users.spec.ts similarity index 100% rename from backend/src/schema/resolvers/users.spec.js rename to backend/src/schema/resolvers/users.spec.ts diff --git a/backend/src/schema/resolvers/users.js b/backend/src/schema/resolvers/users.ts similarity index 100% rename from backend/src/schema/resolvers/users.js rename to backend/src/schema/resolvers/users.ts diff --git a/backend/src/schema/resolvers/users/location.spec.js b/backend/src/schema/resolvers/users/location.spec.ts similarity index 100% rename from backend/src/schema/resolvers/users/location.spec.js rename to backend/src/schema/resolvers/users/location.spec.ts diff --git a/backend/src/schema/resolvers/users/location.js b/backend/src/schema/resolvers/users/location.ts similarity index 98% rename from backend/src/schema/resolvers/users/location.js rename to backend/src/schema/resolvers/users/location.ts index 54d73560b..0c3f55595 100644 --- a/backend/src/schema/resolvers/users/location.js +++ b/backend/src/schema/resolvers/users/location.ts @@ -72,7 +72,7 @@ export const createOrUpdateLocations = async (nodeLabel, nodeId, locationName, s let locationId if (locationName !== null) { - const res = await fetch( + const res: any = await fetch( `https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent( locationName, )}.json?access_token=${ @@ -155,7 +155,7 @@ export const createOrUpdateLocations = async (nodeLabel, nodeId, locationName, s } export const queryLocations = async ({ place, lang }) => { - const res = await fetch( + const res: any = await fetch( `https://api.mapbox.com/geocoding/v5/mapbox.places/${place}.json?access_token=${CONFIG.MAPBOX_TOKEN}&types=region,place,country&language=${lang}`, ) // Return empty array if no location found or error occurred diff --git a/backend/src/schema/resolvers/users/mutedUsers.spec.js b/backend/src/schema/resolvers/users/mutedUsers.spec.ts similarity index 99% rename from backend/src/schema/resolvers/users/mutedUsers.spec.js rename to backend/src/schema/resolvers/users/mutedUsers.spec.ts index 20e37f627..762893af0 100644 --- a/backend/src/schema/resolvers/users/mutedUsers.spec.js +++ b/backend/src/schema/resolvers/users/mutedUsers.spec.ts @@ -59,7 +59,7 @@ describe('mutedUsers', () => { it('throws permission error', async () => { const { query } = createTestClient(server) const result = await query({ query: mutedUserQuery }) - expect(result.errors[0]).toHaveProperty('message', 'Not Authorized!') + expect(result.errors![0]).toHaveProperty('message', 'Not Authorized!') }) describe('authenticated and given a muted user', () => { diff --git a/backend/src/schema/resolvers/viewedTeaserCount.spec.js b/backend/src/schema/resolvers/viewedTeaserCount.spec.ts similarity index 100% rename from backend/src/schema/resolvers/viewedTeaserCount.spec.js rename to backend/src/schema/resolvers/viewedTeaserCount.spec.ts diff --git a/backend/src/schema/types/index.js b/backend/src/schema/types/index.ts similarity index 100% rename from backend/src/schema/types/index.js rename to backend/src/schema/types/index.ts diff --git a/backend/src/schema/types/schema.gql b/backend/src/schema/types/schema.gql index b15179443..9e2d00bca 100644 --- a/backend/src/schema/types/schema.gql +++ b/backend/src/schema/types/schema.gql @@ -1,17 +1,3 @@ -type Mutation { - # Get a JWT Token for the given Email and password - login(email: String!, password: String!): String! - changePassword(oldPassword: String!, newPassword: String!): String! - requestPasswordReset(email: String!): Boolean! - resetPassword(email: String!, nonce: String!, newPassword: String!): Boolean! - # Shout the given Type and ID - shout(id: ID!, type: ShoutTypeEnum): Boolean! - # Unshout the given Type and ID - unshout(id: ID!, type: ShoutTypeEnum): Boolean! - followUser(id: ID!): User - unfollowUser(id: ID!): User -} - enum ShoutTypeEnum { Post } @@ -27,4 +13,4 @@ type Reward { type SharedInboxEndpoint { id: ID! uri: String -} +} \ No newline at end of file diff --git a/backend/src/schema/types/type/Post.gql b/backend/src/schema/types/type/Post.gql index 5a5d57b9a..7c93c0b73 100644 --- a/backend/src/schema/types/type/Post.gql +++ b/backend/src/schema/types/type/Post.gql @@ -85,6 +85,7 @@ input _PostFilter { postsInMyGroups: Boolean postType_in: [PostType] eventStart_gte: String + eventEnd_gte: String } enum _PostOrdering { @@ -233,6 +234,11 @@ type Mutation { pinPost(id: ID!): Post unpinPost(id: ID!): Post markTeaserAsViewed(id: ID!): Post + + # Shout the given Type and ID + shout(id: ID!, type: ShoutTypeEnum): Boolean! + # Unshout the given Type and ID + unshout(id: ID!, type: ShoutTypeEnum): Boolean! } type Query { diff --git a/backend/src/schema/types/type/User.gql b/backend/src/schema/types/type/User.gql index fe1ff43f0..f406e4e45 100644 --- a/backend/src/schema/types/type/User.gql +++ b/backend/src/schema/types/type/User.gql @@ -214,10 +214,21 @@ type Mutation { muteUser(id: ID!): User unmuteUser(id: ID!): User + blockUser(id: ID!): User unblockUser(id: ID!): User + followUser(id: ID!): User + unfollowUser(id: ID!): User + switchUserRole(role: UserRole!, id: ID!): User saveCategorySettings(activeCategories: [String]): Boolean + + requestPasswordReset(email: String!): Boolean! + resetPassword(email: String!, nonce: String!, newPassword: String!): Boolean! + changePassword(oldPassword: String!, newPassword: String!): String! + + # Get a JWT Token for the given Email and password + login(email: String!, password: String!): String! } diff --git a/backend/src/server.spec.js b/backend/src/server.spec.ts similarity index 100% rename from backend/src/server.spec.js rename to backend/src/server.spec.ts diff --git a/backend/src/server.js b/backend/src/server.ts similarity index 96% rename from backend/src/server.js rename to backend/src/server.ts index d0b205035..a76735147 100644 --- a/backend/src/server.js +++ b/backend/src/server.ts @@ -58,7 +58,7 @@ export const context = async (options) => { } } -const createServer = (options) => { +const createServer = (options?) => { const defaults = { context, schema: middleware(schema), @@ -87,12 +87,12 @@ const createServer = (options) => { app.use( helmet( (CONFIG.DEBUG && { contentSecurityPolicy: false, crossOriginEmbedderPolicy: false }) || {}, - ), + ) as any, ) app.use('/.well-known/', webfinger()) app.use(express.static('public')) - app.use(bodyParser.json({ limit: '10mb' })) - app.use(bodyParser.urlencoded({ limit: '10mb', extended: true })) + app.use(bodyParser.json({ limit: '10mb' }) as any) + app.use(bodyParser.urlencoded({ limit: '10mb', extended: true }) as any) app.use(graphqlUploadExpress()) server.applyMiddleware({ app, path: '/' }) const httpServer = http.createServer(app) diff --git a/backend/test/features/support/steps.js b/backend/test/features/support/steps.ts similarity index 99% rename from backend/test/features/support/steps.js rename to backend/test/features/support/steps.ts index e15801f83..c62b286cd 100644 --- a/backend/test/features/support/steps.js +++ b/backend/test/features/support/steps.ts @@ -5,7 +5,7 @@ import { expect } from 'chai' import { GraphQLClient } from 'graphql-request' import Factory from '../../../src/db/factories' const debug = require('debug')('ea:test:steps') - +const host: any = null const client = new GraphQLClient(host) function createUser (slug) { diff --git a/backend/test/features/world.js b/backend/test/features/world.ts similarity index 94% rename from backend/test/features/world.js rename to backend/test/features/world.ts index be436b536..72e120dc7 100644 --- a/backend/test/features/world.js +++ b/backend/test/features/world.ts @@ -4,6 +4,11 @@ import request from 'request' const debug = require('debug')('ea:test:world') class CustomWorld { + lastResponses: any + lastContentType: any + lastInboxUrl: any + lastActivity: any + statusCode: any constructor () { // webFinger.feature this.lastResponses = [] diff --git a/backend/test/setup.js b/backend/test/setup.ts similarity index 87% rename from backend/test/setup.js rename to backend/test/setup.ts index 4501da899..d2f24bd40 100644 --- a/backend/test/setup.js +++ b/backend/test/setup.ts @@ -2,7 +2,7 @@ // https://stackoverflow.com/questions/68468203/why-am-i-getting-textencoder-is-not-defined-in-jest import { TextEncoder, TextDecoder } from 'util' global.TextEncoder = TextEncoder -global.TextDecoder = TextDecoder +global.TextDecoder = TextDecoder as any // Metascraper takes longer nowadays, double time jest.setTimeout(10000) \ No newline at end of file diff --git a/backend/tsconfig.json b/backend/tsconfig.json new file mode 100644 index 000000000..1d58dba0a --- /dev/null +++ b/backend/tsconfig.json @@ -0,0 +1,111 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./build", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": false, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + "useUnknownInCatchVariables": false, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "include": ["./src/**/*"], + "exclude": ["./src/**/*.spec.ts"] +} diff --git a/backend/yarn.lock b/backend/yarn.lock index d576416fc..38c3b62bf 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -1088,6 +1088,13 @@ exec-sh "^0.3.2" minimist "^1.2.0" +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + "@faker-js/faker@7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@faker-js/faker/-/faker-7.6.0.tgz#9ea331766084288634a9247fcd8b84f16ff4ba07" @@ -1237,6 +1244,13 @@ dependencies: jest-get-type "^29.4.2" +"@jest/expect-utils@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.5.0.tgz#f74fad6b6e20f924582dc8ecbf2cb800fe43a036" + integrity sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg== + dependencies: + jest-get-type "^29.4.3" + "@jest/expect@^29.4.2": version "29.4.2" resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.4.2.tgz#2d4a6a41b29380957c5094de19259f87f194578b" @@ -1304,6 +1318,13 @@ dependencies: "@sinclair/typebox" "^0.25.16" +"@jest/schemas@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.3.tgz#39cf1b8469afc40b6f5a2baaa146e332c4151788" + integrity sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg== + dependencies: + "@sinclair/typebox" "^0.25.16" + "@jest/source-map@^29.4.2": version "29.4.2" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.4.2.tgz#f9815d59e25cd3d6828e41489cd239271018d153" @@ -1398,6 +1419,18 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" +"@jest/types@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.5.0.tgz#f59ef9b031ced83047c67032700d8c807d6e1593" + integrity sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog== + dependencies: + "@jest/schemas" "^29.4.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + "@jridgewell/gen-mapping@^0.1.0": version "0.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" @@ -1420,6 +1453,11 @@ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + "@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" @@ -1430,6 +1468,14 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.9": version "0.3.17" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" @@ -1491,10 +1537,10 @@ url-regex "~4.1.1" video-extensions "~1.1.0" -"@metascraper/helpers@^5.33.5", "@metascraper/helpers@^5.34.2", "@metascraper/helpers@^5.34.4": - version "5.34.4" - resolved "https://registry.yarnpkg.com/@metascraper/helpers/-/helpers-5.34.4.tgz#59faf01466938b26aa8df147f97c7f9f4d739d28" - integrity sha512-OZdXkfxJXH5dW+aoptLJzxN56Xj+ABzbqZ9NDuKn908zW4tvLBPD6go3qdd3GXXQZH7TxvWpETn9i1AxzoyKmQ== +"@metascraper/helpers@^5.33.5", "@metascraper/helpers@^5.34.2", "@metascraper/helpers@^5.34.4", "@metascraper/helpers@^5.34.7": + version "5.34.7" + resolved "https://registry.yarnpkg.com/@metascraper/helpers/-/helpers-5.34.7.tgz#749a288813e9f61938bb64d34bfb4e2c26689cbe" + integrity sha512-h3Kg9xFoVlr3rqxbhpR+o7nzYuThXtiDuk+kiaIWozAguUWT6xvwb3iHKuCdKC9/29PXeJ+UqM9WxBamxbzGmg== dependencies: audio-extensions "0.0.0" chrono-node "~2.6.2" @@ -1507,13 +1553,13 @@ is-uri "~1.2.4" iso-639-3 "~2.2.0" isostring "0.0.1" - jsdom "~22.0.0" + jsdom "~22.1.0" lodash "~4.17.21" memoize-one "~6.0.0" microsoft-capitalize "~1.0.5" mime "~3.0.0" normalize-url "~6.1.0" - re2 "~1.18.0" + re2 "~1.18.3" smartquotes "~2.3.2" tldts "~6.0.1" url-regex-safe "~3.0.0" @@ -1724,6 +1770,26 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + "@types/accepts@*", "@types/accepts@^1.3.5": version "1.3.5" resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" @@ -1912,6 +1978,14 @@ dependencies: "@types/istanbul-lib-report" "*" +"@types/jest@^29.5.2": + version "29.5.2" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.2.tgz#86b4afc86e3a8f3005b297ed8a72494f89e6395b" + integrity sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg== + dependencies: + expect "^29.0.0" + pretty-format "^29.0.0" + "@types/json-schema@^7.0.3": version "7.0.3" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636" @@ -1982,6 +2056,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.26.tgz#a8a119960bff16b823be4c617da028570779bcfd" integrity sha512-myMwkO2Cr82kirHY8uknNRHEVtn0wV3DTQfkrjx17jmkstDRZ24gNUdl8AHXVyVclTYI/bNjgTPTAWvWLqXqkw== +"@types/node@^20.2.5": + version "20.2.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.2.5.tgz#26d295f3570323b2837d322180dfbf1ba156fefb" + integrity sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ== + "@types/prettier@^2.1.5": version "2.7.2" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0" @@ -2111,11 +2190,21 @@ acorn-jsx@^5.1.0: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384" integrity sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw== +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + acorn@^7.1.0: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +acorn@^8.4.1: + version "8.8.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== + agent-base@5: version "5.1.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-5.1.1.tgz#e8fb3f242959db44d63be665db7a8e739537a32c" @@ -2586,6 +2675,11 @@ arg@1.0.0: resolved "https://registry.yarnpkg.com/arg/-/arg-1.0.0.tgz#444d885a4e25b121640b55155ef7cd03975d6050" integrity sha512-Wk7TEzl1KqvTGs/uyhmHO/3XLd3t1UeU4IstvPXVzGPM522cTjqjNZ99esCkcL52sjqjo8e8CTBcWhkxvGzoAw== +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -3039,6 +3133,13 @@ browserslist@^4.8.3, browserslist@^4.9.1: escalade "^3.1.1" node-releases "^1.1.71" +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -3235,7 +3336,7 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.0: +chalk@^4.0.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -3525,7 +3626,7 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.19.0, commander@^2.20.3: +commander@^2.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -3684,6 +3785,11 @@ create-error-class@^3.0.0: dependencies: capture-stack-trace "^1.0.0" +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + cross-env@~7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" @@ -3847,10 +3953,10 @@ data-urls@^4.0.0: whatwg-mimetype "^3.0.0" whatwg-url "^12.0.0" -dateformat@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" - integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== +dateformat@^4.6.3: + version "4.6.3" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.6.3.tgz#556fa6497e5217fedb78821424f8a1c22fa3f4b5" + integrity sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA== dayjs@^1.10.0: version "1.10.6" @@ -4020,6 +4126,11 @@ diff-sequences@^29.4.2: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.2.tgz#711fe6bd8a5869fe2539cee4a5152425ff671fda" integrity sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw== +diff-sequences@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" + integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== + diff@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" @@ -4194,16 +4305,16 @@ dot-prop@^4.1.0: dependencies: is-obj "^1.0.0" +dotenv@^16.0.0: + version "16.1.4" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.1.4.tgz#67ac1a10cd9c25f5ba604e4e08bc77c0ebe0ca8c" + integrity sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw== + dotenv@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-4.0.0.tgz#864ef1379aced55ce6f95debecdce179f7a0cd1d" integrity sha512-XcaMACOr3JMVcEv0Y/iUM2XaOsATRZ3U1In41/1jjK6vJZ2PZbQ1bzCG8uvaByfaBpl9gqc9QWJovpUGBXLLYQ== -dotenv@^6.1.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064" - integrity sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w== - dotenv@~8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" @@ -4734,6 +4845,17 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expect@^29.0.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.5.0.tgz#68c0509156cb2a0adb8865d413b137eeaae682f7" + integrity sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg== + dependencies: + "@jest/expect-utils" "^29.5.0" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-util "^29.5.0" + expect@^29.4.2: version "29.4.2" resolved "https://registry.yarnpkg.com/expect/-/expect-29.4.2.tgz#2ae34eb88de797c64a1541ad0f1e2ea8a7a7b492" @@ -4870,7 +4992,7 @@ fast-glob@^3.1.1: merge2 "^1.3.0" micromatch "^4.0.2" -fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -5858,10 +5980,10 @@ insane@2.6.1: assignment "2.0.0" he "0.5.0" -install-artifact-from-github@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/install-artifact-from-github/-/install-artifact-from-github-1.3.2.tgz#1a16d9508e40330523a3017ae0d4713ccc64de82" - integrity sha512-yCFcLvqk0yQdxx0uJz4t9Z3adDMLAYrcGYv546uRXCSvxE+GqNYhhz/KmrGcUKGI/gVLR9n/e/zM9jX/+ASMJQ== +install-artifact-from-github@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/install-artifact-from-github/-/install-artifact-from-github-1.3.3.tgz#57d89bacfa0f47d7307fe41b6247cda9f9a8079c" + integrity sha512-x79SL0d8WOi1ZjXSTUqqs0GPQZ92YArJAN9O46wgU9wdH2U9ecyyhB9YGDbPe2OLV4ptmt6AZYRQZ2GydQZosQ== invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" @@ -6397,6 +6519,16 @@ jest-diff@^29.4.2: jest-get-type "^29.4.2" pretty-format "^29.4.2" +jest-diff@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.5.0.tgz#e0d83a58eb5451dcc1fa61b1c3ee4e8f5a290d63" + integrity sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.4.3" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" + jest-docblock@^29.4.2: version "29.4.2" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.4.2.tgz#c78a95eedf9a24c0a6cc16cf2abdc4b8b0f2531b" @@ -6432,6 +6564,11 @@ jest-get-type@^29.4.2: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.2.tgz#7cb63f154bca8d8f57364d01614477d466fa43fe" integrity sha512-vERN30V5i2N6lqlFu4ljdTqQAgrkTFMC9xaIIfOPYBw04pufjXRty5RuXBiB1d72tGbURa/UgoiHB90ruOSivg== +jest-get-type@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" + integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== + jest-haste-map@^25.2.6: version "25.2.6" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-25.2.6.tgz#4aa6bcfa15310afccdb9ca77af58a98add8cedb8" @@ -6488,6 +6625,16 @@ jest-matcher-utils@^29.4.2: jest-get-type "^29.4.2" pretty-format "^29.4.2" +jest-matcher-utils@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz#d957af7f8c0692c5453666705621ad4abc2c59c5" + integrity sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw== + dependencies: + chalk "^4.0.0" + jest-diff "^29.5.0" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" + jest-message-util@^29.4.2: version "29.4.2" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.4.2.tgz#309a2924eae6ca67cf7f25781a2af1902deee717" @@ -6503,6 +6650,21 @@ jest-message-util@^29.4.2: slash "^3.0.0" stack-utils "^2.0.3" +jest-message-util@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.5.0.tgz#1f776cac3aca332ab8dd2e3b41625435085c900e" + integrity sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.5.0" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.5.0" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-mock@^29.4.2: version "29.4.2" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.4.2.tgz#e1054be66fb3e975d26d4528fcde6979e4759de8" @@ -6653,6 +6815,18 @@ jest-util@^25.2.6: is-ci "^2.0.0" make-dir "^3.0.0" +jest-util@^29.0.0, jest-util@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.5.0.tgz#24a4d3d92fc39ce90425311b23c27a6e0ef16b8f" + integrity sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ== + dependencies: + "@jest/types" "^29.5.0" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + jest-util@^29.4.2: version "29.4.2" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.4.2.tgz#3db8580b295df453a97de4a1b42dd2578dabd2c2" @@ -6747,10 +6921,10 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== -jsdom@~22.0.0: - version "22.0.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-22.0.0.tgz#3295c6992c70089c4b8f5cf060489fddf7ee9816" - integrity sha512-p5ZTEb5h+O+iU02t0GfEjAnkdYPrQSkfuTSMkMYyIoMvUNEHsbG0bHHbfXIcfTqD2UfvjQX7mmgiFsyRwGscVw== +jsdom@~22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-22.1.0.tgz#0fca6d1a37fbeb7f4aac93d1090d782c56b611c8" + integrity sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw== dependencies: abab "^2.0.6" cssstyle "^3.0.0" @@ -6816,7 +6990,7 @@ json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== -json5@^2.1.2, json5@^2.2.2: +json5@^2.1.2, json5@^2.2.2, json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -7041,6 +7215,11 @@ lodash.isstring@^4.0.1: resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= +lodash.memoize@4.x: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + lodash.mergewith@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" @@ -7169,6 +7348,11 @@ make-dir@^3.0.0: dependencies: semver "^6.0.0" +make-error@1.x, make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + make-fetch-happen@^10.0.3: version "10.2.1" resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" @@ -7320,12 +7504,12 @@ metascraper-soundcloud@^5.34.4: dependencies: "@metascraper/helpers" "^5.34.4" -metascraper-title@^5.33.5: - version "5.33.5" - resolved "https://registry.yarnpkg.com/metascraper-title/-/metascraper-title-5.33.5.tgz#2efd6aae03211175fa2e27b4d827cade4c3e35f4" - integrity sha512-Vavt/2Yt4BZP+++xsV2ZnUqqQ4WHxRImZq6fZD6Eh8R8nt43kuQdgKrBKTD3Ybk6/qvlCTQ9XY57m/KTIiAMnA== +metascraper-title@^5.34.7: + version "5.34.7" + resolved "https://registry.yarnpkg.com/metascraper-title/-/metascraper-title-5.34.7.tgz#d53afa05eb4d5f2d7b8ec772ddfc335733f86a21" + integrity sha512-k+eDC12Y1m5n/RE3GhqmWRtNSKH9rDXvAzJ6k2T9+9PyaGeaSN9dWLnc3rK9TYmdFP02kTKhCAV8WerHw/7IqA== dependencies: - "@metascraper/helpers" "^5.33.5" + "@metascraper/helpers" "^5.34.7" metascraper-url@^5.34.2: version "5.34.2" @@ -7402,19 +7586,19 @@ microsoft-capitalize@~1.0.5: resolved "https://registry.yarnpkg.com/microsoft-capitalize/-/microsoft-capitalize-1.0.5.tgz#bcaf915039f14224c8cfd74c31cea42fecacbb31" integrity sha512-iqDMU9J643BHg8Zp7EMZNLTp6Pgs2f1S2SMnCW2VlUqMs17xCZ5vwVjalBJEGVcUfG+/1ePqeEGcMW3VfzHK5A== -migrate@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/migrate/-/migrate-1.7.0.tgz#23fb97aa33145788030a1a91187a0ee32a49acbf" - integrity sha512-I63YykITgWyI+ET4KO8xGePYkR9U7CtSe/RrR13vLbZSpUcAh4/ry2GswNv7Lywcsp3BaDHj7YdjC7ihVYCFmw== +migrate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/migrate/-/migrate-2.0.0.tgz#eef68ac206f658d96ddfaf81c8c5999d71694956" + integrity sha512-Oklla7q1Ok3UZZOGL67wkFlKfZHAxdT7NusHwHgzPBfokbCvYDEEGM8Bx7G5jDuoRNiA7R261Y2CwZX0cyx9CQ== dependencies: - chalk "^2.4.1" - commander "^2.19.0" - dateformat "^3.0.3" - dotenv "^6.1.0" + chalk "^4.1.2" + commander "^2.20.3" + dateformat "^4.6.3" + dotenv "^16.0.0" inherits "^2.0.3" - minimatch "^3.0.4" - mkdirp "^0.5.1" - slug "^0.9.2" + minimatch "^9.0.1" + mkdirp "^3.0.1" + slug "^8.2.2" mime-db@1.43.0: version "1.43.0" @@ -7496,6 +7680,13 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" +minimatch@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.1.tgz#8a555f541cf976c622daf078bb28f29fb927c253" + integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w== + dependencies: + brace-expansion "^2.0.1" + minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" @@ -7609,6 +7800,11 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +mkdirp@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" + integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== + moment@2.21.0: version "2.21.0" resolved "https://registry.yarnpkg.com/moment/-/moment-2.21.0.tgz#2a114b51d2a6ec9e6d83cf803f838a878d8a023a" @@ -7789,7 +7985,7 @@ node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@^2.6.0, node-fetch@~2.6.1: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== -node-gyp@^9.3.0: +node-gyp@^9.3.1: version "9.3.1" resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.3.1.tgz#1e19f5f290afcc9c46973d68700cbd21a96192e4" integrity sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg== @@ -8486,6 +8682,15 @@ prettier@~2.3.2: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== +pretty-format@^29.0.0, pretty-format@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.5.0.tgz#283134e74f70e2e3e7229336de0e4fce94ccde5a" + integrity sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw== + dependencies: + "@jest/schemas" "^29.4.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" + pretty-format@^29.4.2: version "29.4.2" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.4.2.tgz#64bf5ccc0d718c03027d94ac957bdd32b3fb2401" @@ -8646,14 +8851,14 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -re2@~1.18.0: - version "1.18.0" - resolved "https://registry.yarnpkg.com/re2/-/re2-1.18.0.tgz#6d6f47c5aaa436eb7a7d68b260f8cf25d7948619" - integrity sha512-MoCYZlJ9YUgksND9asyNF2/x532daXU/ARp1UeJbQ5flMY6ryKNEhrWt85aw3YluzOJlC3vXpGgK2a1jb0b4GA== +re2@~1.18.3: + version "1.18.3" + resolved "https://registry.yarnpkg.com/re2/-/re2-1.18.3.tgz#64120f3990351e6d71207b095a92ebc41f123c7f" + integrity sha512-QAUSIl5znNR/GOXLIUWWao0pPQ2VZU/t9u+0j17x7lXXypPsil8iuYBsSuMDZ3TGx439332tYdh0d9Nt8XGbHg== dependencies: - install-artifact-from-github "^1.3.1" + install-artifact-from-github "^1.3.3" nan "^2.17.0" - node-gyp "^9.3.0" + node-gyp "^9.3.1" reachable-url@~1.7.1: version "1.7.1" @@ -9192,6 +9397,13 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== +semver@7.x: + version "7.5.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec" + integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== + dependencies: + lru-cache "^6.0.0" + semver@^6.0.0, semver@^6.1.0, semver@^6.1.2, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -9321,12 +9533,10 @@ slice-ansi@^2.1.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" -slug@^0.9.2: - version "0.9.4" - resolved "https://registry.yarnpkg.com/slug/-/slug-0.9.4.tgz#fad5f1ef33150830c7688cd8500514576eccabd8" - integrity sha512-3YHq0TeJ4+AIFbJm+4UWSQs5A1mmeWOTQqydW3OoPmQfNKxlO96NDRTIrp+TBkmvEsEFrd+Z/LXw8OD/6OlZ5g== - dependencies: - unicode ">= 0.3.1" +slug@^8.2.2: + version "8.2.2" + resolved "https://registry.yarnpkg.com/slug/-/slug-8.2.2.tgz#33b019a857a11fc4773c1e9a9f60e3da651a9e5d" + integrity sha512-5ByW6qXqPeG0Tmlkh24JhdXhvQsbaJSjVr3GgGxUV0BSskZKKBZZfFWxezap8+fh1vxBN9GVbqI1V6nqAFxlBg== slug@~6.0.0: version "6.0.0" @@ -10050,6 +10260,39 @@ ts-invariant@^0.4.0: dependencies: tslib "^1.9.3" +ts-jest@^29.1.0: + version "29.1.0" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.0.tgz#4a9db4104a49b76d2b368ea775b6c9535c603891" + integrity sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^29.0.0" + json5 "^2.2.3" + lodash.memoize "4.x" + make-error "1.x" + semver "7.x" + yargs-parser "^21.0.1" + +ts-node@^10.9.1: + version "10.9.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + tslib@1.11.1: version "1.11.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" @@ -10119,6 +10362,11 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" +typescript@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" + integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== + undefsafe@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.2.tgz#225f6b9e0337663e0d8e7cfd686fc2836ccace76" @@ -10154,11 +10402,6 @@ unicode-property-aliases-ecmascript@^1.0.4: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== -"unicode@>= 0.3.1": - version "11.0.1" - resolved "https://registry.yarnpkg.com/unicode/-/unicode-11.0.1.tgz#735bd422ec75cf28d396eb224d535d168d5f1db6" - integrity sha512-+cHtykLb+eF1yrSLWTwcYBrqJkTfX7Quoyg7Juhe6uylF43ZbMdxMuSHNYlnyLT8T7POAvavgBthzUF9AIaQvQ== - union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" @@ -10362,6 +10605,11 @@ uuid@^8.0.0, uuid@~8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + v8-compile-cache@^2.0.3: version "2.1.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" @@ -10645,7 +10893,7 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yargs-parser@^21.1.1: +yargs-parser@^21.0.1, yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== @@ -10663,6 +10911,11 @@ yargs@^17.3.1: y18n "^5.0.5" yargs-parser "^21.1.1" +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" diff --git a/cypress/cypress.config.js b/cypress/cypress.config.js new file mode 100644 index 000000000..2d2cefc47 --- /dev/null +++ b/cypress/cypress.config.js @@ -0,0 +1,53 @@ +const dotenv = require('dotenv') +const { defineConfig } = require("cypress"); +const browserify = require("@badeball/cypress-cucumber-preprocessor/browserify"); +const { addCucumberPreprocessorPlugin } = require("@badeball/cypress-cucumber-preprocessor"); + +// Test persistent(between commands) store +const testStore = {} + +async function setupNodeEvents(on, config) { + await addCucumberPreprocessorPlugin(on, config); + + on("file:preprocessor", browserify.default(config)); + + on("task", { + pushValue({ name, value }) { + testStore[name] = value + return true + }, + getValue(name) { + console.log("getValue",name,testStore) + return testStore[name] + }, + }); + + on("after:run", (results) => { + if (results) { + console.log(results.status); + } + }); + + return config; +} + +// Import backend .env (smart)? +const { parsed } = dotenv.config({ path: '../backend/.env' }) + +module.exports = defineConfig({ + e2e: { + projectId: "qa7fe2", + defaultCommandTimeout: 10000, + chromeWebSecurity: false, + baseUrl: "http://localhost:3000", + specPattern: "cypress/e2e/**/*.feature", + supportFile: "cypress/support/e2e.js", + retries: { + runMode: 2, + openMode: 0, + }, + video: false, + setupNodeEvents, + }, + env: parsed +}); \ No newline at end of file diff --git a/cypress/cypress.json b/cypress/cypress.json deleted file mode 100644 index de323f736..000000000 --- a/cypress/cypress.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "projectId": "qa7fe2", - "defaultCommandTimeout": 10000, - "ignoreTestFiles": "*.js", - "chromeWebSecurity": false, - "baseUrl": "http://localhost:3000", - "video":false, - "retries": { - "runMode": 2, - "openMode": 0 - } -} diff --git a/cypress/integration/Admin.DonationInfo.feature b/cypress/e2e/Admin.DonationInfo.feature similarity index 100% rename from cypress/integration/Admin.DonationInfo.feature rename to cypress/e2e/Admin.DonationInfo.feature diff --git a/cypress/integration/Admin.PinPost.feature b/cypress/e2e/Admin.PinPost.feature similarity index 100% rename from cypress/integration/Admin.PinPost.feature rename to cypress/e2e/Admin.PinPost.feature diff --git a/cypress/integration/Admin.TagOverview.feature b/cypress/e2e/Admin.TagOverview.feature similarity index 100% rename from cypress/integration/Admin.TagOverview.feature rename to cypress/e2e/Admin.TagOverview.feature diff --git a/cypress/integration/Internationalization.feature b/cypress/e2e/Internationalization.feature similarity index 100% rename from cypress/integration/Internationalization.feature rename to cypress/e2e/Internationalization.feature diff --git a/cypress/integration/Moderation.HidePost.feature b/cypress/e2e/Moderation.HidePost.feature similarity index 100% rename from cypress/integration/Moderation.HidePost.feature rename to cypress/e2e/Moderation.HidePost.feature diff --git a/cypress/integration/Moderation.ReportContent.feature b/cypress/e2e/Moderation.ReportContent.feature similarity index 100% rename from cypress/integration/Moderation.ReportContent.feature rename to cypress/e2e/Moderation.ReportContent.feature diff --git a/cypress/integration/Notification.Mention.feature b/cypress/e2e/Notification.Mention.feature similarity index 100% rename from cypress/integration/Notification.Mention.feature rename to cypress/e2e/Notification.Mention.feature diff --git a/cypress/integration/PersistentLinks.feature b/cypress/e2e/PersistentLinks.feature similarity index 100% rename from cypress/integration/PersistentLinks.feature rename to cypress/e2e/PersistentLinks.feature diff --git a/cypress/integration/Post.Comment.feature b/cypress/e2e/Post.Comment.feature similarity index 100% rename from cypress/integration/Post.Comment.feature rename to cypress/e2e/Post.Comment.feature diff --git a/cypress/integration/Post.Create.feature b/cypress/e2e/Post.Create.feature similarity index 100% rename from cypress/integration/Post.Create.feature rename to cypress/e2e/Post.Create.feature diff --git a/cypress/integration/Post.Images.feature b/cypress/e2e/Post.Images.feature similarity index 100% rename from cypress/integration/Post.Images.feature rename to cypress/e2e/Post.Images.feature diff --git a/cypress/integration/Post.feature b/cypress/e2e/Post.feature similarity index 100% rename from cypress/integration/Post.feature rename to cypress/e2e/Post.feature diff --git a/cypress/integration/Search.feature.broken b/cypress/e2e/Search.feature.broken similarity index 100% rename from cypress/integration/Search.feature.broken rename to cypress/e2e/Search.feature.broken diff --git a/cypress/integration/User.Authentication.feature b/cypress/e2e/User.Authentication.feature similarity index 95% rename from cypress/integration/User.Authentication.feature rename to cypress/e2e/User.Authentication.feature index db7680bd4..878ecad4a 100644 --- a/cypress/integration/User.Authentication.feature +++ b/cypress/e2e/User.Authentication.feature @@ -22,5 +22,6 @@ Feature: User authentication Scenario: Log out Given I am logged in as "peter-pan" - When I log out + When I navigate to page "/" + And I log out Then I am on page "login" diff --git a/cypress/integration/User.Block.feature.broken b/cypress/e2e/User.Block.feature.broken similarity index 100% rename from cypress/integration/User.Block.feature.broken rename to cypress/e2e/User.Block.feature.broken diff --git a/cypress/integration/User.Mute.feature.broken b/cypress/e2e/User.Mute.feature.broken similarity index 100% rename from cypress/integration/User.Mute.feature.broken rename to cypress/e2e/User.Mute.feature.broken diff --git a/cypress/integration/User.SettingNotifications.feature b/cypress/e2e/User.SettingNotifications.feature similarity index 100% rename from cypress/integration/User.SettingNotifications.feature rename to cypress/e2e/User.SettingNotifications.feature diff --git a/cypress/integration/UserProfile.Avatar.feature b/cypress/e2e/UserProfile.Avatar.feature similarity index 100% rename from cypress/integration/UserProfile.Avatar.feature rename to cypress/e2e/UserProfile.Avatar.feature diff --git a/cypress/integration/UserProfile.ChangePassword.feature b/cypress/e2e/UserProfile.ChangePassword.feature similarity index 100% rename from cypress/integration/UserProfile.ChangePassword.feature rename to cypress/e2e/UserProfile.ChangePassword.feature diff --git a/cypress/integration/UserProfile.NameDescriptionLocation.feature b/cypress/e2e/UserProfile.NameDescriptionLocation.feature similarity index 100% rename from cypress/integration/UserProfile.NameDescriptionLocation.feature rename to cypress/e2e/UserProfile.NameDescriptionLocation.feature diff --git a/cypress/integration/UserProfile.SocialMedia.feature b/cypress/e2e/UserProfile.SocialMedia.feature similarity index 100% rename from cypress/integration/UserProfile.SocialMedia.feature rename to cypress/e2e/UserProfile.SocialMedia.feature diff --git a/cypress/integration/Admin.DonationInfo/I_click_the_checkbox_show_donations_progress_bar_and_save.js b/cypress/integration/Admin.DonationInfo/I_click_the_checkbox_show_donations_progress_bar_and_save.js deleted file mode 100644 index b4289dd5e..000000000 --- a/cypress/integration/Admin.DonationInfo/I_click_the_checkbox_show_donations_progress_bar_and_save.js +++ /dev/null @@ -1,6 +0,0 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; - -Then("I click the checkbox show donations progress bar and save", () => { - cy.get("#showDonations").click() - cy.get(".donations-info-button").click() -}) \ No newline at end of file diff --git a/cypress/integration/Moderation.ReportContent/I_click_on_the_avatar_menu_in_the_top_right_corner.js b/cypress/integration/Moderation.ReportContent/I_click_on_the_avatar_menu_in_the_top_right_corner.js deleted file mode 100644 index 27830b239..000000000 --- a/cypress/integration/Moderation.ReportContent/I_click_on_the_avatar_menu_in_the_top_right_corner.js +++ /dev/null @@ -1,5 +0,0 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; - -When("I click on the avatar menu in the top right corner", () => { - cy.get(".avatar-menu").click(); -}); \ No newline at end of file diff --git a/cypress/integration/Moderation.ReportContent/I_see_all_the_reported_posts_including_the_one_from_above.js b/cypress/integration/Moderation.ReportContent/I_see_all_the_reported_posts_including_the_one_from_above.js deleted file mode 100644 index 66c9baf61..000000000 --- a/cypress/integration/Moderation.ReportContent/I_see_all_the_reported_posts_including_the_one_from_above.js +++ /dev/null @@ -1,7 +0,0 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; - -Then('I see all the reported posts including the one from above', () => { - cy.get('table tbody').within(() => { - cy.contains('tr', 'The Truth about the Holocaust') - }) -}) \ No newline at end of file diff --git a/cypress/integration/Moderation.ReportContent/somebody_reported_the_following_posts.js b/cypress/integration/Moderation.ReportContent/somebody_reported_the_following_posts.js deleted file mode 100644 index 3ca39e6e6..000000000 --- a/cypress/integration/Moderation.ReportContent/somebody_reported_the_following_posts.js +++ /dev/null @@ -1,22 +0,0 @@ -import { Given } from "cypress-cucumber-preprocessor/steps"; - -Given('somebody reported the following posts:', table => { - table.hashes().forEach(({ submitterEmail, resourceId, reasonCategory, reasonDescription }) => { - const submitter = { - email: submitterEmail, - password: '1234' - } - cy.factory() - .build('user', {}, submitter) - .authenticateAs(submitter) - .mutate(`mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) { - fileReport(resourceId: $resourceId, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription) { - reportId - } - }`, { - resourceId, - reasonCategory, - reasonDescription - }) - }) -}) \ No newline at end of file diff --git a/cypress/integration/User.SettingNotifications/I_click_save.js b/cypress/integration/User.SettingNotifications/I_click_save.js deleted file mode 100644 index 32d702f1e..000000000 --- a/cypress/integration/User.SettingNotifications/I_click_save.js +++ /dev/null @@ -1,5 +0,0 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; - -Then("I click save", () => { - cy.get(".save-button").click() -}) \ No newline at end of file diff --git a/cypress/integration/UserProfile.ChangePassword/I_submit_the_form.js b/cypress/integration/UserProfile.ChangePassword/I_submit_the_form.js deleted file mode 100644 index 18349cff8..000000000 --- a/cypress/integration/UserProfile.ChangePassword/I_submit_the_form.js +++ /dev/null @@ -1,5 +0,0 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; - -When("I submit the form", () => { - cy.get("form").submit(); -}); \ No newline at end of file diff --git a/cypress/integration/common/I_navigate_to_page_{string}.js b/cypress/integration/common/I_navigate_to_page_{string}.js deleted file mode 100644 index aa929c80a..000000000 --- a/cypress/integration/common/I_navigate_to_page_{string}.js +++ /dev/null @@ -1,5 +0,0 @@ -import { Given } from "cypress-cucumber-preprocessor/steps"; - -Given("I navigate to page {string}", page => { - cy.visit(page); -}); \ No newline at end of file diff --git a/cypress/integration/common/I_refresh_the_page.js b/cypress/integration/common/I_refresh_the_page.js deleted file mode 100644 index 1ac655cb4..000000000 --- a/cypress/integration/common/I_refresh_the_page.js +++ /dev/null @@ -1,6 +0,0 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; - -When('I refresh the page', () => { - cy.visit('/') - .reload(); -}); \ No newline at end of file diff --git a/cypress/integration/common/I_wait_for_{int}_milliseconds.js b/cypress/integration/common/I_wait_for_{int}_milliseconds.js deleted file mode 100644 index bc8ef906a..000000000 --- a/cypress/integration/common/I_wait_for_{int}_milliseconds.js +++ /dev/null @@ -1,5 +0,0 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; - -When("I wait for {int} milliseconds", time => { - cy.wait(time) -}); \ No newline at end of file diff --git a/cypress/parallel-features.sh b/cypress/parallel-features.sh index c7d4d4878..24f5bfa9f 100755 --- a/cypress/parallel-features.sh +++ b/cypress/parallel-features.sh @@ -8,10 +8,10 @@ CUR_JOB=$(expr $1 - 1) MAX_JOBS=$2 # Features -FEATURE_LIST=( $(find cypress/integration/ -maxdepth 1 -name "*.feature") ) +FEATURE_LIST=( $(find cypress/e2e/ -maxdepth 1 -name "*.feature") ) # Calculation -MAX_FEATURES=$(find cypress/integration/ -maxdepth 1 -name "*.feature" -print | wc -l) +MAX_FEATURES=$(find cypress/e2e/ -maxdepth 1 -name "*.feature" -print | wc -l) # adds overhead features to the first jobs if [[ $CUR_JOB -lt $(expr ${MAX_FEATURES} % ${MAX_JOBS}) ]] then diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js deleted file mode 100644 index 4e6b440ef..000000000 --- a/cypress/plugins/index.js +++ /dev/null @@ -1,41 +0,0 @@ -// *********************************************************** -// This example plugins/index.js can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - - -const cucumber = require('cypress-cucumber-preprocessor').default -const dotenv = require('dotenv') - -// Import backend .env (smart)? -const { parsed } = dotenv.config({ path: require.resolve('../../backend/.env') }) - -// Test persistent(between commands) store -const testStore = {} - -module.exports = (on, config) => { - config.env.NEO4J_URI = parsed.NEO4J_URI - config.env.NEO4J_USERNAME = parsed.NEO4J_USERNAME - config.env.NEO4J_PASSWORD = parsed.NEO4J_PASSWORD - config.env.JWT_SECRET = parsed.JWT_SECRET - on('file:preprocessor', cucumber()) - on('task', { - pushValue({ name, value }) { - testStore[name] = value - return true - }, - getValue(name) { - console.log("getValue",name,testStore) - return testStore[name] - }, - }) - return config -} \ No newline at end of file diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 7d3738a3d..b80501ce2 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -15,7 +15,7 @@ /* globals Cypress cy */ import "cypress-file-upload"; import { GraphQLClient, request } from 'graphql-request' -import config from '../../backend/src/config' +import CONFIG from '../../backend/build/config' const authenticatedHeaders = (variables) => { const mutation = ` @@ -24,7 +24,7 @@ const authenticatedHeaders = (variables) => { } ` return new Cypress.Promise((resolve, reject) => { - request(config.GRAPHQL_URI, mutation, variables).then((response) => { + request(CONFIG.GRAPHQL_URI, mutation, variables).then((response) => { resolve({ authorization: `Bearer ${response.login}` }) }) }) @@ -40,7 +40,7 @@ Cypress.Commands.add( ({email, password}) => { return new Cypress.Promise((resolve, reject) => { authenticatedHeaders({ email, password }).then((headers) => { - resolve(new GraphQLClient(config.GRAPHQL_URI, { headers })) + resolve(new GraphQLClient(CONFIG.GRAPHQL_URI, { headers })) }) }) }) @@ -48,9 +48,10 @@ Cypress.Commands.add( Cypress.Commands.add( 'mutate', { prevSubject: true }, - (graphQLClient, mutation, variables) => { - return new Cypress.Promise((resolve, reject) => { + (graphQLClient, mutation, variables, response) => { + return new Cypress.Promise(async (resolve, reject) => { graphQLClient.request(mutation, variables).then(() => resolve(graphQLClient)) + }) }) diff --git a/cypress/support/index.js b/cypress/support/e2e.js similarity index 100% rename from cypress/support/index.js rename to cypress/support/e2e.js diff --git a/cypress/support/factories.js b/cypress/support/factories.js index f8f86f9f7..825026346 100644 --- a/cypress/support/factories.js +++ b/cypress/support/factories.js @@ -1,13 +1,7 @@ -import Factory from '../../backend/src/db/factories' -import { getNeode } from '../../backend/src/db/neo4j' +import Factory from '../../backend/build/db/factories' +import { getNeode } from '../../backend/build/db/neo4j' - -const neo4jConfigs = { - uri: Cypress.env('NEO4J_URI'), - username: Cypress.env('NEO4J_USERNAME'), - password: Cypress.env('NEO4J_PASSWORD') -} -const neodeInstance = getNeode(neo4jConfigs) +const neodeInstance = getNeode() beforeEach(() => cy.then(() => neodeInstance.writeCypher('MATCH (everything) DETACH DELETE everything;'))) @@ -16,7 +10,7 @@ Cypress.Commands.add('neode', () => { }) Cypress.Commands.add( - 'first', + 'firstOf', { prevSubject: true }, (neode, model, properties) => { return neode.first(model, properties) diff --git a/cypress/integration/Admin.DonationInfo/the_donation_info_contains_goal_{string}_and_progress_{string}.js b/cypress/support/step_definitions/Admin.DonationInfo/the_donation_info_contains_goal_{string}_and_progress_{string}.js similarity index 75% rename from cypress/integration/Admin.DonationInfo/the_donation_info_contains_goal_{string}_and_progress_{string}.js rename to cypress/support/step_definitions/Admin.DonationInfo/the_donation_info_contains_goal_{string}_and_progress_{string}.js index cd2473800..454aea44b 100644 --- a/cypress/integration/Admin.DonationInfo/the_donation_info_contains_goal_{string}_and_progress_{string}.js +++ b/cypress/support/step_definitions/Admin.DonationInfo/the_donation_info_contains_goal_{string}_and_progress_{string}.js @@ -1,8 +1,8 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("the donation info contains goal {string} and progress {string}", (goal, progress) => { cy.get('.top-info-bar') .should('contain', goal) cy.get('.top-info-bar') .should('contain', progress) -}); \ No newline at end of file +}); diff --git a/cypress/integration/Admin.DonationInfo/the_donation_info_is_{string}.js b/cypress/support/step_definitions/Admin.DonationInfo/the_donation_info_is_{string}.js similarity index 68% rename from cypress/integration/Admin.DonationInfo/the_donation_info_is_{string}.js rename to cypress/support/step_definitions/Admin.DonationInfo/the_donation_info_is_{string}.js index d259e6520..da231f23a 100644 --- a/cypress/integration/Admin.DonationInfo/the_donation_info_is_{string}.js +++ b/cypress/support/step_definitions/Admin.DonationInfo/the_donation_info_is_{string}.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("the donation info is {string}", (visibility) => { cy.get('.top-info-bar') .should(visibility === 'visible' ? 'exist' : 'not.exist') -}) \ No newline at end of file +}) diff --git a/cypress/integration/Admin.PinPost/I_open_the_content_menu_of_post_{string}.js b/cypress/support/step_definitions/Admin.PinPost/I_open_the_content_menu_of_post_{string}.js similarity index 69% rename from cypress/integration/Admin.PinPost/I_open_the_content_menu_of_post_{string}.js rename to cypress/support/step_definitions/Admin.PinPost/I_open_the_content_menu_of_post_{string}.js index a7be22495..2b8d00dc9 100644 --- a/cypress/integration/Admin.PinPost/I_open_the_content_menu_of_post_{string}.js +++ b/cypress/support/step_definitions/Admin.PinPost/I_open_the_content_menu_of_post_{string}.js @@ -1,7 +1,7 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I open the content menu of post {string}", (title) => { cy.contains('.post-teaser', title) .find('.content-menu .base-button') .click() -}) \ No newline at end of file +}) diff --git a/cypress/integration/Admin.PinPost/the_post_with_title_{string}_has_a_ribbon_for_pinned_posts.js b/cypress/support/step_definitions/Admin.PinPost/the_post_with_title_{string}_has_a_ribbon_for_pinned_posts.js similarity index 76% rename from cypress/integration/Admin.PinPost/the_post_with_title_{string}_has_a_ribbon_for_pinned_posts.js rename to cypress/support/step_definitions/Admin.PinPost/the_post_with_title_{string}_has_a_ribbon_for_pinned_posts.js index 1db51d2b0..3e9f43bc3 100644 --- a/cypress/integration/Admin.PinPost/the_post_with_title_{string}_has_a_ribbon_for_pinned_posts.js +++ b/cypress/support/step_definitions/Admin.PinPost/the_post_with_title_{string}_has_a_ribbon_for_pinned_posts.js @@ -1,4 +1,4 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("the post with title {string} has a ribbon for pinned posts", (title) => { cy.get(".post-teaser").contains(title) @@ -6,4 +6,4 @@ Then("the post with title {string} has a ribbon for pinned posts", (title) => { .parent() .find(".ribbon.--pinned") .should("contain", "Announcement") -}) \ No newline at end of file +}) diff --git a/cypress/integration/Admin.PinPost/there_is_no_button_to_pin_a_post.js b/cypress/support/step_definitions/Admin.PinPost/there_is_no_button_to_pin_a_post.js similarity index 72% rename from cypress/integration/Admin.PinPost/there_is_no_button_to_pin_a_post.js rename to cypress/support/step_definitions/Admin.PinPost/there_is_no_button_to_pin_a_post.js index 859b9faf1..70535b920 100644 --- a/cypress/integration/Admin.PinPost/there_is_no_button_to_pin_a_post.js +++ b/cypress/support/step_definitions/Admin.PinPost/there_is_no_button_to_pin_a_post.js @@ -1,7 +1,7 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("there is no button to pin a post", () => { cy.get("a.ds-menu-item-link") .should('contain', "Report Post") // sanity check .should('not.contain', "Pin post") -}) \ No newline at end of file +}) diff --git a/cypress/integration/Internationalization/I_see_a_button_with_the_label_{string}.js b/cypress/support/step_definitions/Internationalization/I_see_a_button_with_the_label_{string}.js similarity index 57% rename from cypress/integration/Internationalization/I_see_a_button_with_the_label_{string}.js rename to cypress/support/step_definitions/Internationalization/I_see_a_button_with_the_label_{string}.js index a67f9d7df..73a4a5e50 100644 --- a/cypress/integration/Internationalization/I_see_a_button_with_the_label_{string}.js +++ b/cypress/support/step_definitions/Internationalization/I_see_a_button_with_the_label_{string}.js @@ -1,5 +1,5 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I see a button with the label {string}", label => { cy.contains("button", label); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Internationalization/I_select_{string}_in_the_language_menu.js b/cypress/support/step_definitions/Internationalization/I_select_{string}_in_the_language_menu.js similarity index 71% rename from cypress/integration/Internationalization/I_select_{string}_in_the_language_menu.js rename to cypress/support/step_definitions/Internationalization/I_select_{string}_in_the_language_menu.js index b850a7573..ba89fd3f5 100644 --- a/cypress/integration/Internationalization/I_select_{string}_in_the_language_menu.js +++ b/cypress/support/step_definitions/Internationalization/I_select_{string}_in_the_language_menu.js @@ -1,8 +1,8 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I select {string} in the language menu", language => { cy.get(".locale-menu") .click(); cy.contains(".locale-menu-popover a", language) .click(); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Internationalization/the_whole_user_interface_appears_in_{string}.js b/cypress/support/step_definitions/Internationalization/the_whole_user_interface_appears_in_{string}.js similarity index 66% rename from cypress/integration/Internationalization/the_whole_user_interface_appears_in_{string}.js rename to cypress/support/step_definitions/Internationalization/the_whole_user_interface_appears_in_{string}.js index 4d80b8a0d..d5a8ac95c 100644 --- a/cypress/integration/Internationalization/the_whole_user_interface_appears_in_{string}.js +++ b/cypress/support/step_definitions/Internationalization/the_whole_user_interface_appears_in_{string}.js @@ -1,8 +1,8 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; -import locales from '../../../webapp/locales' +import { Then } from "@badeball/cypress-cucumber-preprocessor"; +import locales from '../../../../webapp/locales' Then("the whole user interface appears in {string}", language => { const { code } = locales.find((entry) => entry.name === language); cy.get(`html[lang=${code}]`); cy.getCookie("locale").should("have.property", "value", code); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Moderation.HidePost/I_should_see_only_{int}_posts_on_the_newsfeed.js b/cypress/support/step_definitions/Moderation.HidePost/I_should_see_only_{int}_posts_on_the_newsfeed.js similarity index 65% rename from cypress/integration/Moderation.HidePost/I_should_see_only_{int}_posts_on_the_newsfeed.js rename to cypress/support/step_definitions/Moderation.HidePost/I_should_see_only_{int}_posts_on_the_newsfeed.js index 611365bb0..26221ae66 100644 --- a/cypress/integration/Moderation.HidePost/I_should_see_only_{int}_posts_on_the_newsfeed.js +++ b/cypress/support/step_definitions/Moderation.HidePost/I_should_see_only_{int}_posts_on_the_newsfeed.js @@ -1,7 +1,7 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I should see only {int} posts on the newsfeed", posts => { cy.get(".post-teaser") .should("have.length", posts); }); - \ No newline at end of file + diff --git a/cypress/integration/Moderation.HidePost/the_page_{string}_returns_a_404_error_with_a_message.js b/cypress/support/step_definitions/Moderation.HidePost/the_page_{string}_returns_a_404_error_with_a_message.js similarity index 81% rename from cypress/integration/Moderation.HidePost/the_page_{string}_returns_a_404_error_with_a_message.js rename to cypress/support/step_definitions/Moderation.HidePost/the_page_{string}_returns_a_404_error_with_a_message.js index 6d9cfb2ef..538e8a64d 100644 --- a/cypress/integration/Moderation.HidePost/the_page_{string}_returns_a_404_error_with_a_message.js +++ b/cypress/support/step_definitions/Moderation.HidePost/the_page_{string}_returns_a_404_error_with_a_message.js @@ -1,4 +1,4 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("the page {string} returns a 404 error with a message:", (route, message) => { cy.request({ @@ -11,4 +11,4 @@ Then("the page {string} returns a 404 error with a message:", (route, message) = failOnStatusCode: false }); cy.get(".error-message").should("contain", message); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Moderation.ReportContent/I_can_t_see_the_moderation_menu_item.js b/cypress/support/step_definitions/Moderation.ReportContent/I_can_t_see_the_moderation_menu_item.js similarity index 81% rename from cypress/integration/Moderation.ReportContent/I_can_t_see_the_moderation_menu_item.js rename to cypress/support/step_definitions/Moderation.ReportContent/I_can_t_see_the_moderation_menu_item.js index 96706281a..fcb1cb686 100644 --- a/cypress/integration/Moderation.ReportContent/I_can_t_see_the_moderation_menu_item.js +++ b/cypress/support/step_definitions/Moderation.ReportContent/I_can_t_see_the_moderation_menu_item.js @@ -1,4 +1,4 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then(`I can't see the moderation menu item`, () => { cy.get('.avatar-menu-popover') @@ -8,4 +8,4 @@ Then(`I can't see the moderation menu item`, () => { cy.get('.avatar-menu-popover') .find('a[href="/moderation"]', 'Moderation') .should('not.exist') -}) \ No newline at end of file +}) diff --git a/cypress/integration/Moderation.ReportContent/I_can_visit_the_post_page.js b/cypress/support/step_definitions/Moderation.ReportContent/I_can_visit_the_post_page.js similarity index 74% rename from cypress/integration/Moderation.ReportContent/I_can_visit_the_post_page.js rename to cypress/support/step_definitions/Moderation.ReportContent/I_can_visit_the_post_page.js index 8ca69da50..ce846c39a 100644 --- a/cypress/integration/Moderation.ReportContent/I_can_visit_the_post_page.js +++ b/cypress/support/step_definitions/Moderation.ReportContent/I_can_visit_the_post_page.js @@ -1,7 +1,7 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then('I can visit the post page', () => { cy.contains('Fake news').click() cy.location('pathname').should('contain', '/post') .get('.base-card .title').should('contain', 'Fake news') -}) \ No newline at end of file +}) diff --git a/cypress/integration/Moderation.ReportContent/I_click_on_Report_Post_from_the_content_menu_of_the_post.js b/cypress/support/step_definitions/Moderation.ReportContent/I_click_on_Report_Post_from_the_content_menu_of_the_post.js similarity index 74% rename from cypress/integration/Moderation.ReportContent/I_click_on_Report_Post_from_the_content_menu_of_the_post.js rename to cypress/support/step_definitions/Moderation.ReportContent/I_click_on_Report_Post_from_the_content_menu_of_the_post.js index 30682b009..8588e156a 100644 --- a/cypress/integration/Moderation.ReportContent/I_click_on_Report_Post_from_the_content_menu_of_the_post.js +++ b/cypress/support/step_definitions/Moderation.ReportContent/I_click_on_Report_Post_from_the_content_menu_of_the_post.js @@ -1,11 +1,11 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When('I click on "Report Post" from the content menu of the post', () => { cy.contains('.base-card', 'The Truth about the Holocaust') .find('.content-menu .base-button') - .click({force: true}) + .click() cy.get('.popover .ds-menu-item-link') .contains('Report Post') .click() -}) \ No newline at end of file +}) diff --git a/cypress/integration/Moderation.ReportContent/I_click_on_the_author.js b/cypress/support/step_definitions/Moderation.ReportContent/I_click_on_the_author.js similarity index 66% rename from cypress/integration/Moderation.ReportContent/I_click_on_the_author.js rename to cypress/support/step_definitions/Moderation.ReportContent/I_click_on_the_author.js index fad21e1a6..049eb8e72 100644 --- a/cypress/integration/Moderation.ReportContent/I_click_on_the_author.js +++ b/cypress/support/step_definitions/Moderation.ReportContent/I_click_on_the_author.js @@ -1,7 +1,7 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When('I click on the author', () => { cy.get('[data-test="avatarUserLink"]') .click() .url().should('include', '/profile/') -}) \ No newline at end of file +}) diff --git a/cypress/support/step_definitions/Moderation.ReportContent/I_click_on_the_avatar_menu_in_the_top_right_corner.js b/cypress/support/step_definitions/Moderation.ReportContent/I_click_on_the_avatar_menu_in_the_top_right_corner.js new file mode 100644 index 000000000..0bb1e816f --- /dev/null +++ b/cypress/support/step_definitions/Moderation.ReportContent/I_click_on_the_avatar_menu_in_the_top_right_corner.js @@ -0,0 +1,7 @@ +import { When } from "@badeball/cypress-cucumber-preprocessor"; +import 'cypress-network-idle'; + +When("I click on the avatar menu in the top right corner", () => { + cy.get(".avatar-menu").click(); + cy.waitForNetworkIdle(2000); +}); diff --git a/cypress/integration/Moderation.ReportContent/I_confirm_the_reporting_dialog.js b/cypress/support/step_definitions/Moderation.ReportContent/I_confirm_the_reporting_dialog.js similarity index 83% rename from cypress/integration/Moderation.ReportContent/I_confirm_the_reporting_dialog.js rename to cypress/support/step_definitions/Moderation.ReportContent/I_confirm_the_reporting_dialog.js index 4009fa4e8..970c61c00 100644 --- a/cypress/integration/Moderation.ReportContent/I_confirm_the_reporting_dialog.js +++ b/cypress/support/step_definitions/Moderation.ReportContent/I_confirm_the_reporting_dialog.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When(/^I confirm the reporting dialog .*:$/, message => { cy.contains(message) // wait for element to become visible @@ -13,4 +13,4 @@ When(/^I confirm the reporting dialog .*:$/, message => { .contains('Report') .click() }) -}) \ No newline at end of file +}) diff --git a/cypress/integration/Moderation.ReportContent/I_see_all_the_reported_posts_including_from_the_user_who_muted_me.js b/cypress/support/step_definitions/Moderation.ReportContent/I_see_all_the_reported_posts_including_from_the_user_who_muted_me.js similarity index 70% rename from cypress/integration/Moderation.ReportContent/I_see_all_the_reported_posts_including_from_the_user_who_muted_me.js rename to cypress/support/step_definitions/Moderation.ReportContent/I_see_all_the_reported_posts_including_from_the_user_who_muted_me.js index 522cd6c78..8989ecf68 100644 --- a/cypress/integration/Moderation.ReportContent/I_see_all_the_reported_posts_including_from_the_user_who_muted_me.js +++ b/cypress/support/step_definitions/Moderation.ReportContent/I_see_all_the_reported_posts_including_from_the_user_who_muted_me.js @@ -1,7 +1,7 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then('I see all the reported posts including from the user who muted me', () => { cy.get('table tbody').within(() => { cy.contains('tr', 'Fake news') }) -}) \ No newline at end of file +}) diff --git a/cypress/support/step_definitions/Moderation.ReportContent/I_see_all_the_reported_posts_including_the_one_from_above.js b/cypress/support/step_definitions/Moderation.ReportContent/I_see_all_the_reported_posts_including_the_one_from_above.js new file mode 100644 index 000000000..f5cb71f91 --- /dev/null +++ b/cypress/support/step_definitions/Moderation.ReportContent/I_see_all_the_reported_posts_including_the_one_from_above.js @@ -0,0 +1,109 @@ +import { Then } from "@badeball/cypress-cucumber-preprocessor"; + +Then('I see all the reported posts including the one from above', () => { + cy.intercept({ + method: 'POST', + url: '/api', + hostname: 'localhost', + }).as('getReports') + + cy.wait(['@getReports'],{ timeout: 30000 }).then((interception) => { + console.log('Cypress interception:', interception) + cy.wrap(interception.response.statusCode).should('eq', 200) + cy.wrap(interception.request.body) + .should('have.property', 'query', `query ($orderBy: ReportOrdering, $first: Int, $offset: Int, $reviewed: Boolean, $closed: Boolean) { + reports(orderBy: $orderBy, first: $first, offset: $offset, reviewed: $reviewed, closed: $closed) { + id + createdAt + updatedAt + closed + reviewed { + createdAt + updatedAt + disable + moderator { + id + slug + name + __typename + } + __typename + } + resource { + __typename + ... on User { + id + slug + name + disabled + deleted + __typename + } + ... on Comment { + id + contentExcerpt + disabled + deleted + author { + id + slug + name + disabled + deleted + __typename + } + post { + id + slug + title + disabled + deleted + __typename + } + __typename + } + ... on Post { + id + slug + title + disabled + deleted + author { + id + slug + name + disabled + deleted + __typename + } + __typename + } + } + filed { + submitter { + id + slug + name + disabled + deleted + __typename + } + createdAt + reasonCategory + reasonDescription + __typename + } + __typename + } +} +` + ) + cy.wrap(interception.response.body) + .should('have.nested.property', 'data.reports.0.resource.author.id') + .and('equal', 'annoying-user') + }) + + cy.get('table tbody').within(() => { + cy.contains('tr', 'The Truth about the Holocaust') + }) +}) diff --git a/cypress/integration/Moderation.ReportContent/each_list_item_links_to_the_post_page.js b/cypress/support/step_definitions/Moderation.ReportContent/each_list_item_links_to_the_post_page.js similarity index 70% rename from cypress/integration/Moderation.ReportContent/each_list_item_links_to_the_post_page.js rename to cypress/support/step_definitions/Moderation.ReportContent/each_list_item_links_to_the_post_page.js index 9ce69d6de..e174113fc 100644 --- a/cypress/integration/Moderation.ReportContent/each_list_item_links_to_the_post_page.js +++ b/cypress/support/step_definitions/Moderation.ReportContent/each_list_item_links_to_the_post_page.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then('each list item links to the post page', () => { cy.contains('The Truth about the Holocaust').click(); cy.location('pathname').should('contain', '/post') -}) \ No newline at end of file +}) diff --git a/cypress/support/step_definitions/Moderation.ReportContent/somebody_reported_the_following_posts.js b/cypress/support/step_definitions/Moderation.ReportContent/somebody_reported_the_following_posts.js new file mode 100644 index 000000000..38cdbee09 --- /dev/null +++ b/cypress/support/step_definitions/Moderation.ReportContent/somebody_reported_the_following_posts.js @@ -0,0 +1,40 @@ +import { Given } from "@badeball/cypress-cucumber-preprocessor"; +import 'cypress-network-idle'; + +Given('somebody reported the following posts:', table => { + const reportIdRegex = /^[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}$/ + cy.intercept({ + method: 'POST', + url: '/', + hostname: 'localhost', + }).as('postToLocalhost') + + table.hashes().forEach(({ submitterEmail, resourceId, reasonCategory, reasonDescription }) => { + const submitter = { + email: submitterEmail, + password: '1234' + } + cy.factory() + .build('user', {}, submitter) + .authenticateAs(submitter) + .mutate(`mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) { + fileReport(resourceId: $resourceId, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription) { + reportId + } + }`, { + resourceId, + reasonCategory, + reasonDescription + }) + cy.wait(['@postToLocalhost']).then((interception) => { + cy.wrap(interception.response.statusCode).should('eq', 200) + }) + cy.wait(['@postToLocalhost']).then((interception) => { + cy.wrap(interception.response.statusCode).should('eq', 200) + cy.wrap(interception.response.body) + .should('have.nested.property', 'data.fileReport.reportId') + .and('match', reportIdRegex) + }) + cy.waitForNetworkIdle(2000) + }) +}) diff --git a/cypress/integration/Moderation.ReportContent/there_is_an_annoying_user_who_has_muted_me.js b/cypress/support/step_definitions/Moderation.ReportContent/there_is_an_annoying_user_who_has_muted_me.js similarity index 65% rename from cypress/integration/Moderation.ReportContent/there_is_an_annoying_user_who_has_muted_me.js rename to cypress/support/step_definitions/Moderation.ReportContent/there_is_an_annoying_user_who_has_muted_me.js index 8d475ee43..8d61afd61 100644 --- a/cypress/integration/Moderation.ReportContent/there_is_an_annoying_user_who_has_muted_me.js +++ b/cypress/support/step_definitions/Moderation.ReportContent/there_is_an_annoying_user_who_has_muted_me.js @@ -1,13 +1,15 @@ +import { Given } from "@badeball/cypress-cucumber-preprocessor"; + Given("there is an annoying user who has muted me", () => { cy.neode() - .first("User", { + .firstOf("User", { role: 'moderator' }) .then(mutedUser => { cy.neode() - .first("User", { + .firstOf("User", { id: 'user' }) .relateTo(mutedUser, "muted"); }); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Notification.Mention/I_start_to_write_a_new_post_with_the_title_{string}_beginning_with.js b/cypress/support/step_definitions/Notification.Mention/I_start_to_write_a_new_post_with_the_title_{string}_beginning_with.js similarity index 73% rename from cypress/integration/Notification.Mention/I_start_to_write_a_new_post_with_the_title_{string}_beginning_with.js rename to cypress/support/step_definitions/Notification.Mention/I_start_to_write_a_new_post_with_the_title_{string}_beginning_with.js index fde5042c1..b8e705c82 100644 --- a/cypress/integration/Notification.Mention/I_start_to_write_a_new_post_with_the_title_{string}_beginning_with.js +++ b/cypress/support/step_definitions/Notification.Mention/I_start_to_write_a_new_post_with_the_title_{string}_beginning_with.js @@ -1,8 +1,8 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I start to write a new post with the title {string} beginning with:", (title, intro) => { cy.get('input[name="title"]') .type(title); cy.get(".ProseMirror") .type(intro); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Notification.Mention/mention_{string}_in_the_text.js b/cypress/support/step_definitions/Notification.Mention/mention_{string}_in_the_text.js similarity index 70% rename from cypress/integration/Notification.Mention/mention_{string}_in_the_text.js rename to cypress/support/step_definitions/Notification.Mention/mention_{string}_in_the_text.js index fa8a29d4a..e1bd19da0 100644 --- a/cypress/integration/Notification.Mention/mention_{string}_in_the_text.js +++ b/cypress/support/step_definitions/Notification.Mention/mention_{string}_in_the_text.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("mention {string} in the text", mention => { cy.get(".ProseMirror") @@ -6,4 +6,4 @@ When("mention {string} in the text", mention => { cy.get(".suggestion-list__item") .contains(mention) .click(); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Notification.Mention/open_the_notification_menu_and_click_on_the_first_item.js b/cypress/support/step_definitions/Notification.Mention/open_the_notification_menu_and_click_on_the_first_item.js similarity index 79% rename from cypress/integration/Notification.Mention/open_the_notification_menu_and_click_on_the_first_item.js rename to cypress/support/step_definitions/Notification.Mention/open_the_notification_menu_and_click_on_the_first_item.js index 0d3917f38..0143d1ac5 100644 --- a/cypress/integration/Notification.Mention/open_the_notification_menu_and_click_on_the_first_item.js +++ b/cypress/support/step_definitions/Notification.Mention/open_the_notification_menu_and_click_on_the_first_item.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("open the notification menu and click on the first item", () => { cy.get(".notifications-menu") @@ -7,4 +7,4 @@ When("open the notification menu and click on the first item", () => { cy.get(".notification .link") .first() .click({force: true}); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Notification.Mention/see_{int}_unread_notifications_in_the_top_menu.js b/cypress/support/step_definitions/Notification.Mention/see_{int}_unread_notifications_in_the_top_menu.js similarity index 65% rename from cypress/integration/Notification.Mention/see_{int}_unread_notifications_in_the_top_menu.js rename to cypress/support/step_definitions/Notification.Mention/see_{int}_unread_notifications_in_the_top_menu.js index 124b61873..ae1644cef 100644 --- a/cypress/integration/Notification.Mention/see_{int}_unread_notifications_in_the_top_menu.js +++ b/cypress/support/step_definitions/Notification.Mention/see_{int}_unread_notifications_in_the_top_menu.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("see {int} unread notifications in the top menu", count => { cy.get(".notifications-menu") .should("contain", count); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Notification.Mention/the_notification_menu_button_links_to_the_all_notifications_page.js b/cypress/support/step_definitions/Notification.Mention/the_notification_menu_button_links_to_the_all_notifications_page.js similarity index 74% rename from cypress/integration/Notification.Mention/the_notification_menu_button_links_to_the_all_notifications_page.js rename to cypress/support/step_definitions/Notification.Mention/the_notification_menu_button_links_to_the_all_notifications_page.js index e40827a16..a7204978e 100644 --- a/cypress/integration/Notification.Mention/the_notification_menu_button_links_to_the_all_notifications_page.js +++ b/cypress/support/step_definitions/Notification.Mention/the_notification_menu_button_links_to_the_all_notifications_page.js @@ -1,8 +1,8 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("the notification menu button links to the all notifications page", () => { cy.get(".notifications-menu") .click(); cy.location("pathname") .should("contain", "/notifications"); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Notification.Mention/the_unread_counter_is_removed.js b/cypress/support/step_definitions/Notification.Mention/the_unread_counter_is_removed.js similarity index 63% rename from cypress/integration/Notification.Mention/the_unread_counter_is_removed.js rename to cypress/support/step_definitions/Notification.Mention/the_unread_counter_is_removed.js index 3859103e8..6c7ff96f0 100644 --- a/cypress/integration/Notification.Mention/the_unread_counter_is_removed.js +++ b/cypress/support/step_definitions/Notification.Mention/the_unread_counter_is_removed.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("the unread counter is removed", () => { cy.get('.notifications-menu .counter-icon') .should('not.exist'); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Post.Comment/I_comment_the_following.js b/cypress/support/step_definitions/Post.Comment/I_comment_the_following.js similarity index 75% rename from cypress/integration/Post.Comment/I_comment_the_following.js rename to cypress/support/step_definitions/Post.Comment/I_comment_the_following.js index 0f5a5049c..5a64ded50 100644 --- a/cypress/integration/Post.Comment/I_comment_the_following.js +++ b/cypress/support/step_definitions/Post.Comment/I_comment_the_following.js @@ -1,7 +1,7 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I comment the following:", async text => { const comment = text.replace("\n", " ") cy.task('pushValue', { name: 'lastComment', value: comment }) cy.get(".editor .ProseMirror").type(comment); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Post.Comment/I_should_see_an_abbreviated_version_of_my_comment.js b/cypress/support/step_definitions/Post.Comment/I_should_see_an_abbreviated_version_of_my_comment.js similarity index 66% rename from cypress/integration/Post.Comment/I_should_see_an_abbreviated_version_of_my_comment.js rename to cypress/support/step_definitions/Post.Comment/I_should_see_an_abbreviated_version_of_my_comment.js index d0b7940f0..67dc9bef8 100644 --- a/cypress/integration/Post.Comment/I_should_see_an_abbreviated_version_of_my_comment.js +++ b/cypress/support/step_definitions/Post.Comment/I_should_see_an_abbreviated_version_of_my_comment.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I should see an abbreviated version of my comment", () => { cy.get("article.comment-card") .should("contain", "show more") -}); \ No newline at end of file +}); diff --git a/cypress/integration/Post.Comment/I_should_see_my_comment.js b/cypress/support/step_definitions/Post.Comment/I_should_see_my_comment.js similarity index 85% rename from cypress/integration/Post.Comment/I_should_see_my_comment.js rename to cypress/support/step_definitions/Post.Comment/I_should_see_my_comment.js index 8d439b112..7b30ee82d 100644 --- a/cypress/integration/Post.Comment/I_should_see_my_comment.js +++ b/cypress/support/step_definitions/Post.Comment/I_should_see_my_comment.js @@ -1,4 +1,4 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I should see my comment", () => { cy.get("article.comment-card p") @@ -10,4 +10,4 @@ Then("I should see my comment", () => { .and("contain", 'https://') // some url .get(".user-teaser > .info > .text") .should("contain", "today at"); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Post.Comment/I_should_see_the_entirety_of_my_comment.js b/cypress/support/step_definitions/Post.Comment/I_should_see_the_entirety_of_my_comment.js similarity index 65% rename from cypress/integration/Post.Comment/I_should_see_the_entirety_of_my_comment.js rename to cypress/support/step_definitions/Post.Comment/I_should_see_the_entirety_of_my_comment.js index a903fa4d0..9ea48fa05 100644 --- a/cypress/integration/Post.Comment/I_should_see_the_entirety_of_my_comment.js +++ b/cypress/support/step_definitions/Post.Comment/I_should_see_the_entirety_of_my_comment.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I should see the entirety of my comment", () => { cy.get("article.comment-card") .should("not.contain", "show more") -}); \ No newline at end of file +}); diff --git a/cypress/integration/Post.Comment/I_type_in_a_comment_with_{int}_characters.js b/cypress/support/step_definitions/Post.Comment/I_type_in_a_comment_with_{int}_characters.js similarity index 71% rename from cypress/integration/Post.Comment/I_type_in_a_comment_with_{int}_characters.js rename to cypress/support/step_definitions/Post.Comment/I_type_in_a_comment_with_{int}_characters.js index 1522c0e64..ef39bdbf4 100644 --- a/cypress/integration/Post.Comment/I_type_in_a_comment_with_{int}_characters.js +++ b/cypress/support/step_definitions/Post.Comment/I_type_in_a_comment_with_{int}_characters.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I type in a comment with {int} characters", size => { var c=""; @@ -6,4 +6,4 @@ When("I type in a comment with {int} characters", size => { c += "c" } cy.get(".editor .ProseMirror").type(c); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Post.Comment/it_should_create_a_mention_in_the_CommentForm.js b/cypress/support/step_definitions/Post.Comment/it_should_create_a_mention_in_the_CommentForm.js similarity index 70% rename from cypress/integration/Post.Comment/it_should_create_a_mention_in_the_CommentForm.js rename to cypress/support/step_definitions/Post.Comment/it_should_create_a_mention_in_the_CommentForm.js index 3468badad..0e52e0f7a 100644 --- a/cypress/integration/Post.Comment/it_should_create_a_mention_in_the_CommentForm.js +++ b/cypress/support/step_definitions/Post.Comment/it_should_create_a_mention_in_the_CommentForm.js @@ -1,7 +1,7 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("it should create a mention in the CommentForm", () => { cy.get(".ProseMirror a") .should('have.class', 'mention') .should('contain', '@peter-pan') -}) \ No newline at end of file +}) diff --git a/cypress/integration/Post.Comment/my_comment_should_be_successfully_created.js b/cypress/support/step_definitions/Post.Comment/my_comment_should_be_successfully_created.js similarity index 64% rename from cypress/integration/Post.Comment/my_comment_should_be_successfully_created.js rename to cypress/support/step_definitions/Post.Comment/my_comment_should_be_successfully_created.js index 766106ddf..acb94f216 100644 --- a/cypress/integration/Post.Comment/my_comment_should_be_successfully_created.js +++ b/cypress/support/step_definitions/Post.Comment/my_comment_should_be_successfully_created.js @@ -1,5 +1,5 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("my comment should be successfully created", () => { cy.get(".iziToast-message").contains("Comment submitted!"); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Post.Comment/the_editor_should_be_cleared.js b/cypress/support/step_definitions/Post.Comment/the_editor_should_be_cleared.js similarity index 61% rename from cypress/integration/Post.Comment/the_editor_should_be_cleared.js rename to cypress/support/step_definitions/Post.Comment/the_editor_should_be_cleared.js index 579fc2ca9..f6e47313a 100644 --- a/cypress/integration/Post.Comment/the_editor_should_be_cleared.js +++ b/cypress/support/step_definitions/Post.Comment/the_editor_should_be_cleared.js @@ -1,5 +1,5 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("the editor should be cleared", () => { cy.get(".ProseMirror p").should("have.class", "is-empty"); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Post.Create/I_choose_{string}_as_the_title.js b/cypress/support/step_definitions/Post.Create/I_choose_{string}_as_the_title.js similarity index 77% rename from cypress/integration/Post.Create/I_choose_{string}_as_the_title.js rename to cypress/support/step_definitions/Post.Create/I_choose_{string}_as_the_title.js index 9fbf8e58f..a5a292a0c 100644 --- a/cypress/integration/Post.Create/I_choose_{string}_as_the_title.js +++ b/cypress/support/step_definitions/Post.Create/I_choose_{string}_as_the_title.js @@ -1,8 +1,8 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I choose {string} as the title", async title => { const lastPost = {} lastPost.title = title.replace("\n", " "); cy.task('pushValue', { name: 'lastPost', value: lastPost }) cy.get('input[name="title"]').type(lastPost.title); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Post.Create/the_post_was_saved_successfully.js b/cypress/support/step_definitions/Post.Create/the_post_was_saved_successfully.js similarity index 78% rename from cypress/integration/Post.Create/the_post_was_saved_successfully.js rename to cypress/support/step_definitions/Post.Create/the_post_was_saved_successfully.js index eec2f819b..987e477d4 100644 --- a/cypress/integration/Post.Create/the_post_was_saved_successfully.js +++ b/cypress/support/step_definitions/Post.Create/the_post_was_saved_successfully.js @@ -1,8 +1,8 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("the post was saved successfully", async () => { cy.task('getValue', 'lastPost').then(lastPost => { cy.get(".base-card > .title").should("contain", lastPost.title); cy.get(".content").should("contain", lastPost.content); }) -}); \ No newline at end of file +}); diff --git a/cypress/integration/Post.Images/I_add_all_required_fields.js b/cypress/support/step_definitions/Post.Images/I_add_all_required_fields.js similarity index 69% rename from cypress/integration/Post.Images/I_add_all_required_fields.js rename to cypress/support/step_definitions/Post.Images/I_add_all_required_fields.js index 52a95ab52..ce2e88a83 100644 --- a/cypress/integration/Post.Images/I_add_all_required_fields.js +++ b/cypress/support/step_definitions/Post.Images/I_add_all_required_fields.js @@ -1,8 +1,8 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I add all required fields", () => { cy.get('input[name="title"]') .type('new post') .get(".editor .ProseMirror") .type('new post content') - }) \ No newline at end of file + }) diff --git a/cypress/integration/Post.Images/I_should_be_able_to_{string}_a_teaser_image.js b/cypress/support/step_definitions/Post.Images/I_should_be_able_to_{string}_a_teaser_image.js similarity index 93% rename from cypress/integration/Post.Images/I_should_be_able_to_{string}_a_teaser_image.js rename to cypress/support/step_definitions/Post.Images/I_should_be_able_to_{string}_a_teaser_image.js index ce5b54f25..019cc956a 100644 --- a/cypress/integration/Post.Images/I_should_be_able_to_{string}_a_teaser_image.js +++ b/cypress/support/step_definitions/Post.Images/I_should_be_able_to_{string}_a_teaser_image.js @@ -1,4 +1,4 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I should be able to {string} a teaser image", condition => { // cy.reload() @@ -27,4 +27,4 @@ Then("I should be able to {string} a teaser image", condition => { break; } -}) \ No newline at end of file +}) diff --git a/cypress/integration/Post.Images/my_post_has_a_teaser_image.js b/cypress/support/step_definitions/Post.Images/my_post_has_a_teaser_image.js similarity index 66% rename from cypress/integration/Post.Images/my_post_has_a_teaser_image.js rename to cypress/support/step_definitions/Post.Images/my_post_has_a_teaser_image.js index 66ff3c31d..b9ce4b3c7 100644 --- a/cypress/integration/Post.Images/my_post_has_a_teaser_image.js +++ b/cypress/support/step_definitions/Post.Images/my_post_has_a_teaser_image.js @@ -1,7 +1,7 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When('my post has a teaser image', () => { cy.get('.contribution-form .image') .should('exist') .and('have.attr', 'src') -}) \ No newline at end of file +}) diff --git a/cypress/integration/Post.Images/the_first_image_should_not_be_displayed_anymore.js b/cypress/support/step_definitions/Post.Images/the_first_image_should_not_be_displayed_anymore.js similarity index 74% rename from cypress/integration/Post.Images/the_first_image_should_not_be_displayed_anymore.js rename to cypress/support/step_definitions/Post.Images/the_first_image_should_not_be_displayed_anymore.js index 867c97fdf..6388f4458 100644 --- a/cypress/integration/Post.Images/the_first_image_should_not_be_displayed_anymore.js +++ b/cypress/support/step_definitions/Post.Images/the_first_image_should_not_be_displayed_anymore.js @@ -1,4 +1,4 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("the first image should not be displayed anymore", () => { cy.get(".hero-image") @@ -6,4 +6,4 @@ Then("the first image should not be displayed anymore", () => { .get('.hero-image > .image') .should('have.length', 1) .and('have.attr', 'src') -}) \ No newline at end of file +}) diff --git a/cypress/integration/Post.Images/the_post_was_saved_successfully_with_the_{string}_teaser_image.js b/cypress/support/step_definitions/Post.Images/the_post_was_saved_successfully_with_the_{string}_teaser_image.js similarity index 87% rename from cypress/integration/Post.Images/the_post_was_saved_successfully_with_the_{string}_teaser_image.js rename to cypress/support/step_definitions/Post.Images/the_post_was_saved_successfully_with_the_{string}_teaser_image.js index ece83d878..c0571068e 100644 --- a/cypress/integration/Post.Images/the_post_was_saved_successfully_with_the_{string}_teaser_image.js +++ b/cypress/support/step_definitions/Post.Images/the_post_was_saved_successfully_with_the_{string}_teaser_image.js @@ -1,4 +1,4 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("the post was saved successfully with the {string} teaser image", condition => { cy.get(".base-card > .title") @@ -8,4 +8,4 @@ Then("the post was saved successfully with the {string} teaser image", condition .get('.post-page img') .should("have.attr", "src") .and("contains", condition === 'updated' ? 'humanconnection' : 'onourjourney') -}) \ No newline at end of file +}) diff --git a/cypress/integration/Post.Images/the_{string}_post_was_saved_successfully_without_a_teaser_image.js b/cypress/support/step_definitions/Post.Images/the_{string}_post_was_saved_successfully_without_a_teaser_image.js similarity index 86% rename from cypress/integration/Post.Images/the_{string}_post_was_saved_successfully_without_a_teaser_image.js rename to cypress/support/step_definitions/Post.Images/the_{string}_post_was_saved_successfully_without_a_teaser_image.js index abafcf0cc..40245df2b 100644 --- a/cypress/integration/Post.Images/the_{string}_post_was_saved_successfully_without_a_teaser_image.js +++ b/cypress/support/step_definitions/Post.Images/the_{string}_post_was_saved_successfully_without_a_teaser_image.js @@ -1,4 +1,4 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then('the {string} post was saved successfully without a teaser image', condition => { cy.get(".base-card > .title") @@ -9,4 +9,4 @@ Then('the {string} post was saved successfully without a teaser image', conditio .should('exist') .get('.hero-image > .image') .should('not.exist') -}) \ No newline at end of file +}) diff --git a/cypress/integration/Post/the_post_shows_up_on_the_newsfeed_at_position_{int}.js b/cypress/support/step_definitions/Post/the_post_shows_up_on_the_newsfeed_at_position_{int}.js similarity index 79% rename from cypress/integration/Post/the_post_shows_up_on_the_newsfeed_at_position_{int}.js rename to cypress/support/step_definitions/Post/the_post_shows_up_on_the_newsfeed_at_position_{int}.js index 3b42ea58e..f10896a33 100644 --- a/cypress/integration/Post/the_post_shows_up_on_the_newsfeed_at_position_{int}.js +++ b/cypress/support/step_definitions/Post/the_post_shows_up_on_the_newsfeed_at_position_{int}.js @@ -1,8 +1,8 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("the post shows up on the newsfeed at position {int}", index => { const selector = `.post-teaser:nth-child(${index}) > .base-card`; cy.get(selector).should("contain", 'previously created post'); cy.get(selector).should("contain", 'with some content'); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Search/I_select_a_post_entry.js b/cypress/support/step_definitions/Search/I_select_a_post_entry.js similarity index 63% rename from cypress/integration/Search/I_select_a_post_entry.js rename to cypress/support/step_definitions/Search/I_select_a_post_entry.js index 25611f91e..26e673499 100644 --- a/cypress/integration/Search/I_select_a_post_entry.js +++ b/cypress/support/step_definitions/Search/I_select_a_post_entry.js @@ -1,7 +1,7 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I select a post entry", () => { cy.get(".searchable-input .search-post") .first() .trigger("click"); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Search/I_select_a_user_entry.js b/cypress/support/step_definitions/Search/I_select_a_user_entry.js similarity index 63% rename from cypress/integration/Search/I_select_a_user_entry.js rename to cypress/support/step_definitions/Search/I_select_a_user_entry.js index b7222b2fb..3d186ffd8 100644 --- a/cypress/integration/Search/I_select_a_user_entry.js +++ b/cypress/support/step_definitions/Search/I_select_a_user_entry.js @@ -1,7 +1,7 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I select a user entry", () => { cy.get(".searchable-input .user-teaser") .first() .trigger("click"); -}) \ No newline at end of file +}) diff --git a/cypress/integration/Search/I_should_have_one_item_in_the_select_dropdown.js b/cypress/support/step_definitions/Search/I_should_have_one_item_in_the_select_dropdown.js similarity index 71% rename from cypress/integration/Search/I_should_have_one_item_in_the_select_dropdown.js rename to cypress/support/step_definitions/Search/I_should_have_one_item_in_the_select_dropdown.js index 7e5188ab6..148bb8195 100644 --- a/cypress/integration/Search/I_should_have_one_item_in_the_select_dropdown.js +++ b/cypress/support/step_definitions/Search/I_should_have_one_item_in_the_select_dropdown.js @@ -1,7 +1,7 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I should have one item in the select dropdown", () => { cy.get(".searchable-input .ds-select-dropdown").should($li => { expect($li).to.have.length(1); }); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Search/I_should_not_see_posts_without_the_searched-for_term_in_the_select_dropdown.js b/cypress/support/step_definitions/Search/I_should_not_see_posts_without_the_searched-for_term_in_the_select_dropdown.js similarity index 72% rename from cypress/integration/Search/I_should_not_see_posts_without_the_searched-for_term_in_the_select_dropdown.js rename to cypress/support/step_definitions/Search/I_should_not_see_posts_without_the_searched-for_term_in_the_select_dropdown.js index a76ed6a5d..d2a2bc1df 100644 --- a/cypress/integration/Search/I_should_not_see_posts_without_the_searched-for_term_in_the_select_dropdown.js +++ b/cypress/support/step_definitions/Search/I_should_not_see_posts_without_the_searched-for_term_in_the_select_dropdown.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I should not see posts without the searched-for term in the select dropdown", () => { cy.get(".ds-select-dropdown") .should("not.contain","No searched for content"); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Search/I_should_see_posts_with_the_searched-for_term_in_the_select_dropdown.js b/cypress/support/step_definitions/Search/I_should_see_posts_with_the_searched-for_term_in_the_select_dropdown.js similarity index 73% rename from cypress/integration/Search/I_should_see_posts_with_the_searched-for_term_in_the_select_dropdown.js rename to cypress/support/step_definitions/Search/I_should_see_posts_with_the_searched-for_term_in_the_select_dropdown.js index ce755abb0..41c132dea 100644 --- a/cypress/integration/Search/I_should_see_posts_with_the_searched-for_term_in_the_select_dropdown.js +++ b/cypress/support/step_definitions/Search/I_should_see_posts_with_the_searched-for_term_in_the_select_dropdown.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I should see posts with the searched-for term in the select dropdown", () => { cy.get(".ds-select-dropdown") .should("contain","101 Essays that will change the way you think"); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Search/I_should_see_the_following_posts_on_the_search_results_page.js b/cypress/support/step_definitions/Search/I_should_see_the_following_posts_on_the_search_results_page.js similarity index 73% rename from cypress/integration/Search/I_should_see_the_following_posts_on_the_search_results_page.js rename to cypress/support/step_definitions/Search/I_should_see_the_following_posts_on_the_search_results_page.js index f703a04f5..3e5da72f7 100644 --- a/cypress/integration/Search/I_should_see_the_following_posts_on_the_search_results_page.js +++ b/cypress/support/step_definitions/Search/I_should_see_the_following_posts_on_the_search_results_page.js @@ -1,8 +1,8 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I should see the following posts on the search results page:", table => { table.hashes().forEach(({ title }) => { cy.get(".post-teaser") .should("contain",title) }); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Search/I_should_see_the_following_users_in_the_select_dropdown.js b/cypress/support/step_definitions/Search/I_should_see_the_following_users_in_the_select_dropdown.js similarity index 77% rename from cypress/integration/Search/I_should_see_the_following_users_in_the_select_dropdown.js rename to cypress/support/step_definitions/Search/I_should_see_the_following_users_in_the_select_dropdown.js index 3e5e14043..830e19a8d 100644 --- a/cypress/integration/Search/I_should_see_the_following_users_in_the_select_dropdown.js +++ b/cypress/support/step_definitions/Search/I_should_see_the_following_users_in_the_select_dropdown.js @@ -1,8 +1,8 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I should see the following users in the select dropdown:", table => { cy.get(".search-heading").should("contain", "Users"); table.hashes().forEach(({ slug }) => { cy.get(".ds-select-dropdown").should("contain", slug); }); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Search/I_type_{string}_and_press_Enter.js b/cypress/support/step_definitions/Search/I_type_{string}_and_press_Enter.js similarity index 71% rename from cypress/integration/Search/I_type_{string}_and_press_Enter.js rename to cypress/support/step_definitions/Search/I_type_{string}_and_press_Enter.js index 1a0fc6d42..796820ba0 100644 --- a/cypress/integration/Search/I_type_{string}_and_press_Enter.js +++ b/cypress/support/step_definitions/Search/I_type_{string}_and_press_Enter.js @@ -1,8 +1,8 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I type {string} and press Enter", value => { cy.get(".searchable-input .ds-select input") .focus() .type(value) .type("{enter}", { force: true }); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Search/I_type_{string}_and_press_escape.js b/cypress/support/step_definitions/Search/I_type_{string}_and_press_escape.js similarity index 68% rename from cypress/integration/Search/I_type_{string}_and_press_escape.js rename to cypress/support/step_definitions/Search/I_type_{string}_and_press_escape.js index a3cde6cda..3e2e67be8 100644 --- a/cypress/integration/Search/I_type_{string}_and_press_escape.js +++ b/cypress/support/step_definitions/Search/I_type_{string}_and_press_escape.js @@ -1,8 +1,8 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I type {string} and press escape", value => { cy.get(".searchable-input .ds-select input") .focus() .type(value) .type("{esc}"); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Search/the_search_field_should_clear.js b/cypress/support/step_definitions/Search/the_search_field_should_clear.js similarity index 64% rename from cypress/integration/Search/the_search_field_should_clear.js rename to cypress/support/step_definitions/Search/the_search_field_should_clear.js index f571cdbd4..10f73959f 100644 --- a/cypress/integration/Search/the_search_field_should_clear.js +++ b/cypress/support/step_definitions/Search/the_search_field_should_clear.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("the search field should clear", () => { cy.get(".searchable-input .ds-select input") .should("have.text", ""); -}); \ No newline at end of file +}); diff --git a/cypress/integration/Search/the_search_parameter_equals_{string}.js b/cypress/support/step_definitions/Search/the_search_parameter_equals_{string}.js similarity index 61% rename from cypress/integration/Search/the_search_parameter_equals_{string}.js rename to cypress/support/step_definitions/Search/the_search_parameter_equals_{string}.js index b8473584c..0f433cf1f 100644 --- a/cypress/integration/Search/the_search_parameter_equals_{string}.js +++ b/cypress/support/step_definitions/Search/the_search_parameter_equals_{string}.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("the search parameter equals {string}", search => { cy.location("search") .should("eq", search); -}); \ No newline at end of file +}); diff --git a/cypress/integration/User.Authentication/I_am_logged_in_with_username_{string}.js b/cypress/support/step_definitions/User.Authentication/I_am_logged_in_with_username_{string}.js similarity index 74% rename from cypress/integration/User.Authentication/I_am_logged_in_with_username_{string}.js rename to cypress/support/step_definitions/User.Authentication/I_am_logged_in_with_username_{string}.js index 4383282bd..d4af04ff6 100644 --- a/cypress/integration/User.Authentication/I_am_logged_in_with_username_{string}.js +++ b/cypress/support/step_definitions/User.Authentication/I_am_logged_in_with_username_{string}.js @@ -1,7 +1,7 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I am logged in with username {string}", name => { cy.get(".avatar-menu").click(); cy.get(".avatar-menu-popover").contains(name); cy.get(".avatar-menu").click(); // Close menu again -}); \ No newline at end of file +}); diff --git a/cypress/integration/User.Block/I_block_the_user_{string}.js b/cypress/support/step_definitions/User.Block/I_block_the_user_{string}.js similarity index 50% rename from cypress/integration/User.Block/I_block_the_user_{string}.js rename to cypress/support/step_definitions/User.Block/I_block_the_user_{string}.js index cde1d96b9..be82f00d9 100644 --- a/cypress/integration/User.Block/I_block_the_user_{string}.js +++ b/cypress/support/step_definitions/User.Block/I_block_the_user_{string}.js @@ -1,11 +1,11 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I block the user {string}", name => { cy.neode() - .first("User", { name }) + .firstOf("User", { name }) .then(blockedUser => { cy.neode() - .first("User", {id: "id-of-peter-pan"}) + .firstOf("User", {id: "id-of-peter-pan"}) .relateTo(blockedUser, "blocked"); }); -}); \ No newline at end of file +}); diff --git a/cypress/integration/User.Block/I_should_not_see_{string}_button.js b/cypress/support/step_definitions/User.Block/I_should_not_see_{string}_button.js similarity index 64% rename from cypress/integration/User.Block/I_should_not_see_{string}_button.js rename to cypress/support/step_definitions/User.Block/I_should_not_see_{string}_button.js index 5bf0b7a68..791a5aaaf 100644 --- a/cypress/integration/User.Block/I_should_not_see_{string}_button.js +++ b/cypress/support/step_definitions/User.Block/I_should_not_see_{string}_button.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then('I should not see {string} button', button => { cy.get('.base-card .action-buttons') .should('have.length', 1) -}) \ No newline at end of file +}) diff --git a/cypress/integration/User.Block/I_should_see_no_users_in_my_blocked_users_list.js b/cypress/support/step_definitions/User.Block/I_should_see_no_users_in_my_blocked_users_list.js similarity index 69% rename from cypress/integration/User.Block/I_should_see_no_users_in_my_blocked_users_list.js rename to cypress/support/step_definitions/User.Block/I_should_see_no_users_in_my_blocked_users_list.js index 11161ef2f..3e4813fbc 100644 --- a/cypress/integration/User.Block/I_should_see_no_users_in_my_blocked_users_list.js +++ b/cypress/support/step_definitions/User.Block/I_should_see_no_users_in_my_blocked_users_list.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I should see no users in my blocked users list", () => { cy.get('.ds-placeholder') .should('contain', "So far, you have not blocked anybody.") -}) \ No newline at end of file +}) diff --git a/cypress/integration/User.Block/I_should_see_the_{string}_button.js b/cypress/support/step_definitions/User.Block/I_should_see_the_{string}_button.js similarity index 67% rename from cypress/integration/User.Block/I_should_see_the_{string}_button.js rename to cypress/support/step_definitions/User.Block/I_should_see_the_{string}_button.js index 373800870..7e6b7eacb 100644 --- a/cypress/integration/User.Block/I_should_see_the_{string}_button.js +++ b/cypress/support/step_definitions/User.Block/I_should_see_the_{string}_button.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then('I should see the {string} button', button => { cy.get('.base-card .action-buttons .base-button') .should('contain', button) -}) \ No newline at end of file +}) diff --git a/cypress/integration/User.Block/I_{string}_see_{string}_from_the_content_menu_in_the_user_info_box.js b/cypress/support/step_definitions/User.Block/I_{string}_see_{string}_from_the_content_menu_in_the_user_info_box.js similarity index 79% rename from cypress/integration/User.Block/I_{string}_see_{string}_from_the_content_menu_in_the_user_info_box.js rename to cypress/support/step_definitions/User.Block/I_{string}_see_{string}_from_the_content_menu_in_the_user_info_box.js index 0f44b5192..bcfd9bd7a 100644 --- a/cypress/integration/User.Block/I_{string}_see_{string}_from_the_content_menu_in_the_user_info_box.js +++ b/cypress/support/step_definitions/User.Block/I_{string}_see_{string}_from_the_content_menu_in_the_user_info_box.js @@ -1,7 +1,7 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I {string} see {string} from the content menu in the user info box", (condition, link) => { cy.get(".user-content-menu .base-button").click() cy.get(".popover .ds-menu-item-link") .should(condition === 'should' ? 'contain' : 'not.contain', link) -}) \ No newline at end of file +}) diff --git a/cypress/integration/User.Block/a_user_has_blocked_me.js b/cypress/support/step_definitions/User.Block/a_user_has_blocked_me.js similarity index 65% rename from cypress/integration/User.Block/a_user_has_blocked_me.js rename to cypress/support/step_definitions/User.Block/a_user_has_blocked_me.js index d1703407f..13b247ccf 100644 --- a/cypress/integration/User.Block/a_user_has_blocked_me.js +++ b/cypress/support/step_definitions/User.Block/a_user_has_blocked_me.js @@ -1,15 +1,15 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("a user has blocked me", () => { cy.neode() - .first("User", { + .firstOf("User", { name: "Peter Pan" }) .then(blockedUser => { cy.neode() - .first("User", { + .firstOf("User", { name: 'Harassing User' }) .relateTo(blockedUser, "blocked"); }); -}); \ No newline at end of file +}); diff --git a/cypress/integration/User.Block/they_should_not_see_the_comment_form.js b/cypress/support/step_definitions/User.Block/they_should_not_see_the_comment_form.js similarity index 65% rename from cypress/integration/User.Block/they_should_not_see_the_comment_form.js rename to cypress/support/step_definitions/User.Block/they_should_not_see_the_comment_form.js index 962934994..34aa86aaf 100644 --- a/cypress/integration/User.Block/they_should_not_see_the_comment_form.js +++ b/cypress/support/step_definitions/User.Block/they_should_not_see_the_comment_form.js @@ -1,5 +1,5 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("they should not see the comment form", () => { cy.get(".base-card").children().should('not.have.class', 'comment-form') -}) \ No newline at end of file +}) diff --git a/cypress/integration/User.Block/they_should_see_a_text_explaining_why_commenting_is_not_possible.js b/cypress/support/step_definitions/User.Block/they_should_see_a_text_explaining_why_commenting_is_not_possible.js similarity index 73% rename from cypress/integration/User.Block/they_should_see_a_text_explaining_why_commenting_is_not_possible.js rename to cypress/support/step_definitions/User.Block/they_should_see_a_text_explaining_why_commenting_is_not_possible.js index d95f3229c..64f0f0fd1 100644 --- a/cypress/integration/User.Block/they_should_see_a_text_explaining_why_commenting_is_not_possible.js +++ b/cypress/support/step_definitions/User.Block/they_should_see_a_text_explaining_why_commenting_is_not_possible.js @@ -1,5 +1,5 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("they should see a text explaining why commenting is not possible", () => { cy.get('.ds-placeholder').should('contain', "Commenting is not possible at this time on this post.") -}) \ No newline at end of file +}) diff --git a/cypress/integration/User.Mute/I_mute_the_user_{string}.js b/cypress/support/step_definitions/User.Mute/I_mute_the_user_{string}.js similarity index 59% rename from cypress/integration/User.Mute/I_mute_the_user_{string}.js rename to cypress/support/step_definitions/User.Mute/I_mute_the_user_{string}.js index e0ed382cb..7b52ca373 100644 --- a/cypress/integration/User.Mute/I_mute_the_user_{string}.js +++ b/cypress/support/step_definitions/User.Mute/I_mute_the_user_{string}.js @@ -1,13 +1,13 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I mute the user {string}", name => { cy.neode() - .first("User", { name }) + .firstOf("User", { name }) .then(mutedUser => { cy.neode() - .first("User", { + .firstOf("User", { name: "Peter Pan" }) .relateTo(mutedUser, "muted"); }); -}); \ No newline at end of file +}); diff --git a/cypress/integration/User.Mute/the_list_of_posts_of_this_user_is_empty.js b/cypress/support/step_definitions/User.Mute/the_list_of_posts_of_this_user_is_empty.js similarity index 69% rename from cypress/integration/User.Mute/the_list_of_posts_of_this_user_is_empty.js rename to cypress/support/step_definitions/User.Mute/the_list_of_posts_of_this_user_is_empty.js index 038ca2168..66ac3bdb8 100644 --- a/cypress/integration/User.Mute/the_list_of_posts_of_this_user_is_empty.js +++ b/cypress/support/step_definitions/User.Mute/the_list_of_posts_of_this_user_is_empty.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("the list of posts of this user is empty", () => { cy.get(".base-card").not(".post-link"); cy.get(".main-container").find(".ds-space.hc-empty"); -}); \ No newline at end of file +}); diff --git a/cypress/integration/User.Mute/the_search_should_contain_the_annoying_user.js b/cypress/support/step_definitions/User.Mute/the_search_should_contain_the_annoying_user.js similarity index 83% rename from cypress/integration/User.Mute/the_search_should_contain_the_annoying_user.js rename to cypress/support/step_definitions/User.Mute/the_search_should_contain_the_annoying_user.js index d29eafc2f..7d47c48aa 100644 --- a/cypress/integration/User.Mute/the_search_should_contain_the_annoying_user.js +++ b/cypress/support/step_definitions/User.Mute/the_search_should_contain_the_annoying_user.js @@ -1,4 +1,4 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("the search should contain the annoying user", () => { cy.get(".searchable-input .ds-select-dropdown") @@ -10,4 +10,4 @@ Then("the search should contain the annoying user", () => { cy.get(".searchable-input .ds-select input") .focus() .type("{esc}"); -}) \ No newline at end of file +}) diff --git a/cypress/integration/User.Mute/the_search_should_not_contain_posts_by_the_annoying_user.js b/cypress/support/step_definitions/User.Mute/the_search_should_not_contain_posts_by_the_annoying_user.js similarity index 81% rename from cypress/integration/User.Mute/the_search_should_not_contain_posts_by_the_annoying_user.js rename to cypress/support/step_definitions/User.Mute/the_search_should_not_contain_posts_by_the_annoying_user.js index a2f0a01d7..1dad99678 100644 --- a/cypress/integration/User.Mute/the_search_should_not_contain_posts_by_the_annoying_user.js +++ b/cypress/support/step_definitions/User.Mute/the_search_should_not_contain_posts_by_the_annoying_user.js @@ -1,4 +1,4 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("the search should not contain posts by the annoying user", () => { cy.get(".searchable-input .ds-select-dropdown").should($li => { @@ -7,4 +7,4 @@ Then("the search should not contain posts by the annoying user", () => { cy.get(".ds-select-dropdown") .should("not.have.class", '.search-post') .should("not.contain", 'Spam') -}); \ No newline at end of file +}); diff --git a/cypress/integration/User.SettingNotifications/I_click_on_element_with_ID_{string}.js b/cypress/support/step_definitions/User.SettingNotifications/I_click_on_element_with_ID_{string}.js similarity index 57% rename from cypress/integration/User.SettingNotifications/I_click_on_element_with_ID_{string}.js rename to cypress/support/step_definitions/User.SettingNotifications/I_click_on_element_with_ID_{string}.js index 251c38941..7bdb20e5d 100644 --- a/cypress/integration/User.SettingNotifications/I_click_on_element_with_ID_{string}.js +++ b/cypress/support/step_definitions/User.SettingNotifications/I_click_on_element_with_ID_{string}.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I click on element with ID {string}", (id) => { cy.get('#' + id).click() diff --git a/cypress/support/step_definitions/User.SettingNotifications/I_click_save.js b/cypress/support/step_definitions/User.SettingNotifications/I_click_save.js new file mode 100644 index 000000000..9412d7912 --- /dev/null +++ b/cypress/support/step_definitions/User.SettingNotifications/I_click_save.js @@ -0,0 +1,5 @@ +import { Then } from "@badeball/cypress-cucumber-preprocessor"; + +Then("I click save", () => { + cy.get(".save-button").click() +}) diff --git a/cypress/integration/UserProfile.Avatar/I_cannot_upload_a_picture.js b/cypress/support/step_definitions/UserProfile.Avatar/I_cannot_upload_a_picture.js similarity index 71% rename from cypress/integration/UserProfile.Avatar/I_cannot_upload_a_picture.js rename to cypress/support/step_definitions/UserProfile.Avatar/I_cannot_upload_a_picture.js index 8b501f3f5..9e44b55ba 100644 --- a/cypress/integration/UserProfile.Avatar/I_cannot_upload_a_picture.js +++ b/cypress/support/step_definitions/UserProfile.Avatar/I_cannot_upload_a_picture.js @@ -1,8 +1,8 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I cannot upload a picture", () => { cy.get(".base-card") .children() .should("not.have.id", "customdropzone") .should("have.class", "profile-avatar"); -}); \ No newline at end of file +}); diff --git a/cypress/integration/UserProfile.Avatar/I_should_be_able_to_change_my_profile_picture.js b/cypress/support/step_definitions/UserProfile.Avatar/I_should_be_able_to_change_my_profile_picture.js similarity index 88% rename from cypress/integration/UserProfile.Avatar/I_should_be_able_to_change_my_profile_picture.js rename to cypress/support/step_definitions/UserProfile.Avatar/I_should_be_able_to_change_my_profile_picture.js index 366fd8292..27be5a99d 100644 --- a/cypress/integration/UserProfile.Avatar/I_should_be_able_to_change_my_profile_picture.js +++ b/cypress/support/step_definitions/UserProfile.Avatar/I_should_be_able_to_change_my_profile_picture.js @@ -1,4 +1,4 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I should be able to change my profile picture", () => { const avatarUpload = "onourjourney.png"; @@ -14,4 +14,4 @@ Then("I should be able to change my profile picture", () => { .and("contains", "onourjourney"); cy.contains(".iziToast-message", "Upload successful") .should("have.length",1); -}); \ No newline at end of file +}); diff --git a/cypress/integration/UserProfile.ChangePassword/I_can_login_successfully.js b/cypress/support/step_definitions/UserProfile.ChangePassword/I_can_login_successfully.js similarity index 66% rename from cypress/integration/UserProfile.ChangePassword/I_can_login_successfully.js rename to cypress/support/step_definitions/UserProfile.ChangePassword/I_can_login_successfully.js index d1a62cc4d..1349b5eb9 100644 --- a/cypress/integration/UserProfile.ChangePassword/I_can_login_successfully.js +++ b/cypress/support/step_definitions/UserProfile.ChangePassword/I_can_login_successfully.js @@ -1,7 +1,7 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I can login successfully", () => { // cy.reload(); cy.get(".iziToast-wrapper") .should("contain", "You are logged in!"); -}); \ No newline at end of file +}); diff --git a/cypress/integration/UserProfile.ChangePassword/I_cannot_login_anymore.js b/cypress/support/step_definitions/UserProfile.ChangePassword/I_cannot_login_anymore.js similarity index 69% rename from cypress/integration/UserProfile.ChangePassword/I_cannot_login_anymore.js rename to cypress/support/step_definitions/UserProfile.ChangePassword/I_cannot_login_anymore.js index ff381d891..f6159c79b 100644 --- a/cypress/integration/UserProfile.ChangePassword/I_cannot_login_anymore.js +++ b/cypress/support/step_definitions/UserProfile.ChangePassword/I_cannot_login_anymore.js @@ -1,7 +1,7 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I cannot login anymore", password => { //cy.reload(); cy.get(".iziToast-wrapper") .should("contain", "Incorrect email address or password."); -}); \ No newline at end of file +}); diff --git a/cypress/integration/UserProfile.ChangePassword/I_cannot_submit_the_form.js b/cypress/support/step_definitions/UserProfile.ChangePassword/I_cannot_submit_the_form.js similarity index 60% rename from cypress/integration/UserProfile.ChangePassword/I_cannot_submit_the_form.js rename to cypress/support/step_definitions/UserProfile.ChangePassword/I_cannot_submit_the_form.js index 657d38bd8..02a2c7d83 100644 --- a/cypress/integration/UserProfile.ChangePassword/I_cannot_submit_the_form.js +++ b/cypress/support/step_definitions/UserProfile.ChangePassword/I_cannot_submit_the_form.js @@ -1,6 +1,6 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I cannot submit the form", () => { cy.get("button[type=submit]") .should('be.disabled'); -}); \ No newline at end of file +}); diff --git a/cypress/integration/UserProfile.ChangePassword/I_fill_the_password_form_with.js b/cypress/support/step_definitions/UserProfile.ChangePassword/I_fill_the_password_form_with.js similarity index 81% rename from cypress/integration/UserProfile.ChangePassword/I_fill_the_password_form_with.js rename to cypress/support/step_definitions/UserProfile.ChangePassword/I_fill_the_password_form_with.js index 69345ecc6..af0c6639b 100644 --- a/cypress/integration/UserProfile.ChangePassword/I_fill_the_password_form_with.js +++ b/cypress/support/step_definitions/UserProfile.ChangePassword/I_fill_the_password_form_with.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I fill the password form with:", table => { table = table.rowsHash(); @@ -8,4 +8,4 @@ When("I fill the password form with:", table => { .type(table["Your new password"]) .get("input[id=passwordConfirmation]") .type(table["Confirm new password"]); -}); \ No newline at end of file +}); diff --git a/cypress/support/step_definitions/UserProfile.ChangePassword/I_submit_the_form.js b/cypress/support/step_definitions/UserProfile.ChangePassword/I_submit_the_form.js new file mode 100644 index 000000000..8b17f6de1 --- /dev/null +++ b/cypress/support/step_definitions/UserProfile.ChangePassword/I_submit_the_form.js @@ -0,0 +1,5 @@ +import { When } from "@badeball/cypress-cucumber-preprocessor"; + +When("I submit the form", () => { + cy.get("form").submit(); +}); diff --git a/cypress/integration/UserProfile.NameDescriptionLocation/I_can_see_my_new_name_{string}_when_I_click_on_my_profile_picture_in_the_top_right.js b/cypress/support/step_definitions/UserProfile.NameDescriptionLocation/I_can_see_my_new_name_{string}_when_I_click_on_my_profile_picture_in_the_top_right.js similarity index 85% rename from cypress/integration/UserProfile.NameDescriptionLocation/I_can_see_my_new_name_{string}_when_I_click_on_my_profile_picture_in_the_top_right.js rename to cypress/support/step_definitions/UserProfile.NameDescriptionLocation/I_can_see_my_new_name_{string}_when_I_click_on_my_profile_picture_in_the_top_right.js index ca6b4798b..c5dd84bf0 100644 --- a/cypress/integration/UserProfile.NameDescriptionLocation/I_can_see_my_new_name_{string}_when_I_click_on_my_profile_picture_in_the_top_right.js +++ b/cypress/support/step_definitions/UserProfile.NameDescriptionLocation/I_can_see_my_new_name_{string}_when_I_click_on_my_profile_picture_in_the_top_right.js @@ -1,4 +1,4 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then('I can see my new name {string} when I click on my profile picture in the top right', name => { cy.get(".avatar-menu").then(($menu) => { diff --git a/cypress/integration/UserProfile.NameDescriptionLocation/I_have_the_following_self-description.js b/cypress/support/step_definitions/UserProfile.NameDescriptionLocation/I_have_the_following_self-description.js similarity index 80% rename from cypress/integration/UserProfile.NameDescriptionLocation/I_have_the_following_self-description.js rename to cypress/support/step_definitions/UserProfile.NameDescriptionLocation/I_have_the_following_self-description.js index a1bc1c524..f0f6ba4da 100644 --- a/cypress/integration/UserProfile.NameDescriptionLocation/I_have_the_following_self-description.js +++ b/cypress/support/step_definitions/UserProfile.NameDescriptionLocation/I_have_the_following_self-description.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When('I have the following self-description:', text => { cy.get('textarea[id=about]') @@ -9,4 +9,4 @@ When('I have the following self-description:', text => { .not('[disabled]') cy.get('.iziToast-message') .should('contain', 'Your data was successfully updated') - }) \ No newline at end of file + }) diff --git a/cypress/integration/UserProfile.NameDescriptionLocation/I_save_{string}_as_my_location.js b/cypress/support/step_definitions/UserProfile.NameDescriptionLocation/I_save_{string}_as_my_location.js similarity index 82% rename from cypress/integration/UserProfile.NameDescriptionLocation/I_save_{string}_as_my_location.js rename to cypress/support/step_definitions/UserProfile.NameDescriptionLocation/I_save_{string}_as_my_location.js index de5143b9f..00d5141f8 100644 --- a/cypress/integration/UserProfile.NameDescriptionLocation/I_save_{string}_as_my_location.js +++ b/cypress/support/step_definitions/UserProfile.NameDescriptionLocation/I_save_{string}_as_my_location.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When('I save {string} as my location', location => { cy.get('input[id=city]').type(location) @@ -10,4 +10,4 @@ When('I save {string} as my location', location => { .not('[disabled]') cy.get('.iziToast-message') .should('contain', 'Your data was successfully updated') - }) \ No newline at end of file + }) diff --git a/cypress/integration/UserProfile.NameDescriptionLocation/I_save_{string}_as_my_new_name.js b/cypress/support/step_definitions/UserProfile.NameDescriptionLocation/I_save_{string}_as_my_new_name.js similarity index 79% rename from cypress/integration/UserProfile.NameDescriptionLocation/I_save_{string}_as_my_new_name.js rename to cypress/support/step_definitions/UserProfile.NameDescriptionLocation/I_save_{string}_as_my_new_name.js index 22e26cbc5..b94683a5b 100644 --- a/cypress/integration/UserProfile.NameDescriptionLocation/I_save_{string}_as_my_new_name.js +++ b/cypress/support/step_definitions/UserProfile.NameDescriptionLocation/I_save_{string}_as_my_new_name.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When('I save {string} as my new name', name => { cy.get('input[id=name]') @@ -9,4 +9,4 @@ When('I save {string} as my new name', name => { .not('[disabled]') cy.get('.iziToast-message') .should('contain', 'Your data was successfully updated') -}) \ No newline at end of file +}) diff --git a/cypress/integration/UserProfile.NameDescriptionLocation/they_can_see_the_following_text_in_the_info_box_below_my_avatar.js b/cypress/support/step_definitions/UserProfile.NameDescriptionLocation/they_can_see_the_following_text_in_the_info_box_below_my_avatar.js similarity index 60% rename from cypress/integration/UserProfile.NameDescriptionLocation/they_can_see_the_following_text_in_the_info_box_below_my_avatar.js rename to cypress/support/step_definitions/UserProfile.NameDescriptionLocation/they_can_see_the_following_text_in_the_info_box_below_my_avatar.js index 6d375a406..d416c8d10 100644 --- a/cypress/integration/UserProfile.NameDescriptionLocation/they_can_see_the_following_text_in_the_info_box_below_my_avatar.js +++ b/cypress/support/step_definitions/UserProfile.NameDescriptionLocation/they_can_see_the_following_text_in_the_info_box_below_my_avatar.js @@ -1,5 +1,5 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When('they can see the following text in the info box below my avatar:', text => { cy.contains(text) -}) \ No newline at end of file +}) diff --git a/cypress/integration/UserProfile.NameDescriptionLocation/they_can_see_{string}_in_the_info_box_below_my_avatar.js b/cypress/support/step_definitions/UserProfile.NameDescriptionLocation/they_can_see_{string}_in_the_info_box_below_my_avatar.js similarity index 60% rename from cypress/integration/UserProfile.NameDescriptionLocation/they_can_see_{string}_in_the_info_box_below_my_avatar.js rename to cypress/support/step_definitions/UserProfile.NameDescriptionLocation/they_can_see_{string}_in_the_info_box_below_my_avatar.js index ea328f441..ea8cf2158 100644 --- a/cypress/integration/UserProfile.NameDescriptionLocation/they_can_see_{string}_in_the_info_box_below_my_avatar.js +++ b/cypress/support/step_definitions/UserProfile.NameDescriptionLocation/they_can_see_{string}_in_the_info_box_below_my_avatar.js @@ -1,5 +1,5 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then('they can see {string} in the info box below my avatar', location => { cy.contains(location) -}) \ No newline at end of file +}) diff --git a/cypress/integration/UserProfile.SocialMedia/I_add_a_social_media_link.js b/cypress/support/step_definitions/UserProfile.SocialMedia/I_add_a_social_media_link.js similarity index 77% rename from cypress/integration/UserProfile.SocialMedia/I_add_a_social_media_link.js rename to cypress/support/step_definitions/UserProfile.SocialMedia/I_add_a_social_media_link.js index 07c80b30c..eab8ba0d6 100644 --- a/cypress/integration/UserProfile.SocialMedia/I_add_a_social_media_link.js +++ b/cypress/support/step_definitions/UserProfile.SocialMedia/I_add_a_social_media_link.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When('I add a social media link', () => { cy.get('[data-test="add-save-button"]') @@ -7,4 +7,4 @@ When('I add a social media link', () => { .type('https://freeradical.zone/peter-pan') .get('[data-test="add-save-button"]') .click() -}) \ No newline at end of file +}) diff --git a/cypress/integration/UserProfile.SocialMedia/I_can_cancel_editing.js b/cypress/support/step_definitions/UserProfile.SocialMedia/I_can_cancel_editing.js similarity index 67% rename from cypress/integration/UserProfile.SocialMedia/I_can_cancel_editing.js rename to cypress/support/step_definitions/UserProfile.SocialMedia/I_can_cancel_editing.js index 03d60c44a..72d83c9a3 100644 --- a/cypress/integration/UserProfile.SocialMedia/I_can_cancel_editing.js +++ b/cypress/support/step_definitions/UserProfile.SocialMedia/I_can_cancel_editing.js @@ -1,8 +1,8 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then('I can cancel editing', () => { cy.get('button#cancel') .click() .get('input#editSocialMedia') .should('have.length', 0) -}) \ No newline at end of file +}) diff --git a/cypress/support/step_definitions/UserProfile.SocialMedia/I_delete_a_social_media_link.js b/cypress/support/step_definitions/UserProfile.SocialMedia/I_delete_a_social_media_link.js new file mode 100644 index 000000000..1f0f3e22e --- /dev/null +++ b/cypress/support/step_definitions/UserProfile.SocialMedia/I_delete_a_social_media_link.js @@ -0,0 +1,6 @@ +import { When } from "@badeball/cypress-cucumber-preprocessor"; + +When('I delete a social media link', () => { + cy.get(".base-button[title='Delete']") + .click() +}) diff --git a/cypress/integration/UserProfile.SocialMedia/I_delete_the_social_media_link_{string}.js b/cypress/support/step_definitions/UserProfile.SocialMedia/I_delete_the_social_media_link_{string}.js similarity index 72% rename from cypress/integration/UserProfile.SocialMedia/I_delete_the_social_media_link_{string}.js rename to cypress/support/step_definitions/UserProfile.SocialMedia/I_delete_the_social_media_link_{string}.js index 6b65e361b..3acba4756 100644 --- a/cypress/integration/UserProfile.SocialMedia/I_delete_the_social_media_link_{string}.js +++ b/cypress/support/step_definitions/UserProfile.SocialMedia/I_delete_the_social_media_link_{string}.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When('I delete the social media link {string}', (link) => { cy.get('[data-test="delete-button"]') @@ -8,5 +8,5 @@ When('I delete the social media link {string}', (link) => { cy.get('[data-test="confirm-button"]') .click() cy.get('.ds-list-item-content > a') - .contains(link).should('not.exist') -}) \ No newline at end of file + .should('not.exist') +}) diff --git a/cypress/integration/UserProfile.SocialMedia/I_edit_and_save_the_link.js b/cypress/support/step_definitions/UserProfile.SocialMedia/I_edit_and_save_the_link.js similarity index 74% rename from cypress/integration/UserProfile.SocialMedia/I_edit_and_save_the_link.js rename to cypress/support/step_definitions/UserProfile.SocialMedia/I_edit_and_save_the_link.js index 54712920d..3cec61688 100644 --- a/cypress/integration/UserProfile.SocialMedia/I_edit_and_save_the_link.js +++ b/cypress/support/step_definitions/UserProfile.SocialMedia/I_edit_and_save_the_link.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When('I edit and save the link', () => { cy.get('input#editSocialMedia') @@ -6,4 +6,4 @@ When('I edit and save the link', () => { .type('https://freeradical.zone/tinkerbell') .get('[data-test="add-save-button"]') .click() -}) \ No newline at end of file +}) diff --git a/cypress/support/step_definitions/UserProfile.SocialMedia/I_have_added_a_social_media_link.js b/cypress/support/step_definitions/UserProfile.SocialMedia/I_have_added_a_social_media_link.js new file mode 100644 index 000000000..b1eb698de --- /dev/null +++ b/cypress/support/step_definitions/UserProfile.SocialMedia/I_have_added_a_social_media_link.js @@ -0,0 +1,13 @@ +import { Given } from "@badeball/cypress-cucumber-preprocessor"; + +Given('I have added a social media link', () => { + cy.visit('/settings/my-social-media') + .get('button') + .contains('Add link') + .click() + .get('#editSocialMedia') + .type('https://freeradical.zone/peter-pan') + .get('button') + .contains('Save') + .click() +}) diff --git a/cypress/integration/UserProfile.SocialMedia/I_have_added_the_social_media_link_{string}.js b/cypress/support/step_definitions/UserProfile.SocialMedia/I_have_added_the_social_media_link_{string}.js similarity index 82% rename from cypress/integration/UserProfile.SocialMedia/I_have_added_the_social_media_link_{string}.js rename to cypress/support/step_definitions/UserProfile.SocialMedia/I_have_added_the_social_media_link_{string}.js index 78a0191d2..d0daab843 100644 --- a/cypress/integration/UserProfile.SocialMedia/I_have_added_the_social_media_link_{string}.js +++ b/cypress/support/step_definitions/UserProfile.SocialMedia/I_have_added_the_social_media_link_{string}.js @@ -1,4 +1,4 @@ -import { Given } from "cypress-cucumber-preprocessor/steps"; +import { Given } from "@badeball/cypress-cucumber-preprocessor"; Given('I have added the social media link {string}', (link) => { cy.visit('/settings/my-social-media') @@ -10,4 +10,4 @@ Given('I have added the social media link {string}', (link) => { .click() cy.get('.ds-list-item-content > a') .contains(link) -}) \ No newline at end of file +}) diff --git a/cypress/integration/UserProfile.SocialMedia/I_start_editing_a_social_media_link.js b/cypress/support/step_definitions/UserProfile.SocialMedia/I_start_editing_a_social_media_link.js similarity index 60% rename from cypress/integration/UserProfile.SocialMedia/I_start_editing_a_social_media_link.js rename to cypress/support/step_definitions/UserProfile.SocialMedia/I_start_editing_a_social_media_link.js index e3e5c2a22..11ee84084 100644 --- a/cypress/integration/UserProfile.SocialMedia/I_start_editing_a_social_media_link.js +++ b/cypress/support/step_definitions/UserProfile.SocialMedia/I_start_editing_a_social_media_link.js @@ -1,6 +1,6 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When('I start editing a social media link', () => { cy.get('[data-test="edit-button"]') .click() -}) \ No newline at end of file +}) diff --git a/cypress/integration/UserProfile.SocialMedia/the_new_social_media_link_shows_up_on_the_page.js b/cypress/support/step_definitions/UserProfile.SocialMedia/the_new_social_media_link_shows_up_on_the_page.js similarity index 69% rename from cypress/integration/UserProfile.SocialMedia/the_new_social_media_link_shows_up_on_the_page.js rename to cypress/support/step_definitions/UserProfile.SocialMedia/the_new_social_media_link_shows_up_on_the_page.js index e72546f2a..fd1bf9350 100644 --- a/cypress/integration/UserProfile.SocialMedia/the_new_social_media_link_shows_up_on_the_page.js +++ b/cypress/support/step_definitions/UserProfile.SocialMedia/the_new_social_media_link_shows_up_on_the_page.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then('the new social media link shows up on the page', () => { cy.get('a[href="https://freeradical.zone/peter-pan"]') .should('have.length', 1) -}) \ No newline at end of file +}) diff --git a/cypress/integration/UserProfile.SocialMedia/the_new_url_is_displayed.js b/cypress/support/step_definitions/UserProfile.SocialMedia/the_new_url_is_displayed.js similarity index 65% rename from cypress/integration/UserProfile.SocialMedia/the_new_url_is_displayed.js rename to cypress/support/step_definitions/UserProfile.SocialMedia/the_new_url_is_displayed.js index c25e6f0bb..c9c7dd906 100644 --- a/cypress/integration/UserProfile.SocialMedia/the_new_url_is_displayed.js +++ b/cypress/support/step_definitions/UserProfile.SocialMedia/the_new_url_is_displayed.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then('the new url is displayed', () => { cy.get("a[href='https://freeradical.zone/tinkerbell']") .should('have.length', 1) -}) \ No newline at end of file +}) diff --git a/cypress/integration/UserProfile.SocialMedia/the_old_url_is_not_displayed.js b/cypress/support/step_definitions/UserProfile.SocialMedia/the_old_url_is_not_displayed.js similarity index 66% rename from cypress/integration/UserProfile.SocialMedia/the_old_url_is_not_displayed.js rename to cypress/support/step_definitions/UserProfile.SocialMedia/the_old_url_is_not_displayed.js index b3e804124..c0941f600 100644 --- a/cypress/integration/UserProfile.SocialMedia/the_old_url_is_not_displayed.js +++ b/cypress/support/step_definitions/UserProfile.SocialMedia/the_old_url_is_not_displayed.js @@ -1,7 +1,7 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then('the old url is not displayed', () => { cy.get("a[href='https://freeradical.zone/peter-pan']") .should('have.length', 0) }) - \ No newline at end of file + diff --git a/cypress/integration/UserProfile.SocialMedia/they_should_be_able_to_see_my_social_media_links.js b/cypress/support/step_definitions/UserProfile.SocialMedia/they_should_be_able_to_see_my_social_media_links.js similarity index 77% rename from cypress/integration/UserProfile.SocialMedia/they_should_be_able_to_see_my_social_media_links.js rename to cypress/support/step_definitions/UserProfile.SocialMedia/they_should_be_able_to_see_my_social_media_links.js index 89db2bd77..3b1692b59 100644 --- a/cypress/integration/UserProfile.SocialMedia/they_should_be_able_to_see_my_social_media_links.js +++ b/cypress/support/step_definitions/UserProfile.SocialMedia/they_should_be_able_to_see_my_social_media_links.js @@ -1,8 +1,8 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then('they should be able to see my social media links', () => { cy.get('[data-test="social-media-list-headline"]') .contains('Peter Pan') .get('a[href="https://freeradical.zone/peter-pan"]') .should('have.length', 1) -}) \ No newline at end of file +}) diff --git a/cypress/integration/common/I_am_logged_in_as_{string}.js b/cypress/support/step_definitions/common/I_am_logged_in_as_{string}.js similarity index 71% rename from cypress/integration/common/I_am_logged_in_as_{string}.js rename to cypress/support/step_definitions/common/I_am_logged_in_as_{string}.js index 96d1c28ab..a44d522da 100644 --- a/cypress/integration/common/I_am_logged_in_as_{string}.js +++ b/cypress/support/step_definitions/common/I_am_logged_in_as_{string}.js @@ -1,9 +1,9 @@ -import { Given } from "cypress-cucumber-preprocessor/steps"; -import encode from '../../../backend/src/jwt/encode' +import { Given } from "@badeball/cypress-cucumber-preprocessor"; +import encode from '../../../../backend/build/jwt/encode' Given("I am logged in as {string}", slug => { cy.neode() - .first("User", { slug }) + .firstOf("User", { slug }) .then(user => { return new Cypress.Promise((resolve, reject) => { if(!user) { @@ -15,4 +15,4 @@ Given("I am logged in as {string}", slug => { .then(user => { cy.setCookie('ocelot-social-token', encode(user)) }) -}); \ No newline at end of file +}); diff --git a/cypress/integration/common/I_am_on_page_{string}.js b/cypress/support/step_definitions/common/I_am_on_page_{string}.js similarity index 61% rename from cypress/integration/common/I_am_on_page_{string}.js rename to cypress/support/step_definitions/common/I_am_on_page_{string}.js index 5ef1b9852..44b10c4c4 100644 --- a/cypress/integration/common/I_am_on_page_{string}.js +++ b/cypress/support/step_definitions/common/I_am_on_page_{string}.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I am on page {string}", page => { cy.location("pathname") .should("match", new RegExp(page)); -}); \ No newline at end of file +}); diff --git a/cypress/integration/common/I_can_see_the_following_table.js b/cypress/support/step_definitions/common/I_can_see_the_following_table.js similarity index 84% rename from cypress/integration/common/I_can_see_the_following_table.js rename to cypress/support/step_definitions/common/I_can_see_the_following_table.js index 9ebe1208c..f62e1a99a 100644 --- a/cypress/integration/common/I_can_see_the_following_table.js +++ b/cypress/support/step_definitions/common/I_can_see_the_following_table.js @@ -1,4 +1,4 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then('I can see the following table:', table => { const headers = table.raw()[0] @@ -13,4 +13,4 @@ Then('I can see the following table:', table => { .eq(i) .should('contain', expected) }) -}) \ No newline at end of file +}) diff --git a/cypress/integration/common/I_choose_the_following_text_as_content.js b/cypress/support/step_definitions/common/I_choose_the_following_text_as_content.js similarity index 81% rename from cypress/integration/common/I_choose_the_following_text_as_content.js rename to cypress/support/step_definitions/common/I_choose_the_following_text_as_content.js index 62b5426d5..0cb974004 100644 --- a/cypress/integration/common/I_choose_the_following_text_as_content.js +++ b/cypress/support/step_definitions/common/I_choose_the_following_text_as_content.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I choose the following text as content:", async text => { cy.task('getValue', 'lastPost').then(lastPost => { @@ -6,4 +6,4 @@ When("I choose the following text as content:", async text => { cy.task('pushValue', { name: 'lastPost', value: lastPost }) cy.get(".editor .ProseMirror").type(lastPost.content); }) -}); \ No newline at end of file +}); diff --git a/cypress/integration/common/I_click_on_{string}.js b/cypress/support/step_definitions/common/I_click_on_{string}.js similarity index 88% rename from cypress/integration/common/I_click_on_{string}.js rename to cypress/support/step_definitions/common/I_click_on_{string}.js index 5f43eb912..9d51f27f7 100644 --- a/cypress/integration/common/I_click_on_{string}.js +++ b/cypress/support/step_definitions/common/I_click_on_{string}.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I click on {string}", element => { const elementSelectors = { @@ -16,4 +16,4 @@ When("I click on {string}", element => { cy.get(elementSelectors[element]) .click() .wait(750); -}); \ No newline at end of file +}); diff --git a/cypress/integration/common/I_click_on_{string}_from_the_content_menu_in_the_user_info_box.js b/cypress/support/step_definitions/common/I_click_on_{string}_from_the_content_menu_in_the_user_info_box.js similarity index 79% rename from cypress/integration/common/I_click_on_{string}_from_the_content_menu_in_the_user_info_box.js rename to cypress/support/step_definitions/common/I_click_on_{string}_from_the_content_menu_in_the_user_info_box.js index f1a859bfe..66373037e 100644 --- a/cypress/integration/common/I_click_on_{string}_from_the_content_menu_in_the_user_info_box.js +++ b/cypress/support/step_definitions/common/I_click_on_{string}_from_the_content_menu_in_the_user_info_box.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I click on {string} from the content menu in the user info box", button => { @@ -9,4 +9,4 @@ When("I click on {string} from the content menu in the user info box", force: true }); } -); \ No newline at end of file +); diff --git a/cypress/integration/User.SettingNotifications/I_click_the_checkbox_show_donations_progress_bar_and_save.js b/cypress/support/step_definitions/common/I_click_the_checkbox_show_donations_progress_bar_and_save.js similarity index 69% rename from cypress/integration/User.SettingNotifications/I_click_the_checkbox_show_donations_progress_bar_and_save.js rename to cypress/support/step_definitions/common/I_click_the_checkbox_show_donations_progress_bar_and_save.js index b4289dd5e..1806af807 100644 --- a/cypress/integration/User.SettingNotifications/I_click_the_checkbox_show_donations_progress_bar_and_save.js +++ b/cypress/support/step_definitions/common/I_click_the_checkbox_show_donations_progress_bar_and_save.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I click the checkbox show donations progress bar and save", () => { cy.get("#showDonations").click() cy.get(".donations-info-button").click() -}) \ No newline at end of file +}) diff --git a/cypress/integration/common/I_fill_in_my_credentials_{string}_{string}.js b/cypress/support/step_definitions/common/I_fill_in_my_credentials_{string}_{string}.js similarity index 81% rename from cypress/integration/common/I_fill_in_my_credentials_{string}_{string}.js rename to cypress/support/step_definitions/common/I_fill_in_my_credentials_{string}_{string}.js index e2227f454..3c0b0d02e 100644 --- a/cypress/integration/common/I_fill_in_my_credentials_{string}_{string}.js +++ b/cypress/support/step_definitions/common/I_fill_in_my_credentials_{string}_{string}.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I fill in my credentials {string} {string}", (email,password) => { cy.get("input[name=email]") @@ -9,4 +9,4 @@ When("I fill in my credentials {string} {string}", (email,password) => { .trigger("focus") .type('{selectall}{backspace}') .type(password); -}); \ No newline at end of file +}); diff --git a/cypress/integration/common/I_follow_the_user_{string}.js b/cypress/support/step_definitions/common/I_follow_the_user_{string}.js similarity index 60% rename from cypress/integration/common/I_follow_the_user_{string}.js rename to cypress/support/step_definitions/common/I_follow_the_user_{string}.js index 56d50a5ae..3698daee8 100644 --- a/cypress/integration/common/I_follow_the_user_{string}.js +++ b/cypress/support/step_definitions/common/I_follow_the_user_{string}.js @@ -1,11 +1,13 @@ +import { Given } from "@badeball/cypress-cucumber-preprocessor"; + Given("I follow the user {string}", name => { cy.neode() - .first("User", {name}) + .firstOf("User", {name}) .then(followed => { cy.neode() - .first("User", { + .firstOf("User", { name: "Peter Pan" }) .relateTo(followed, "following"); }); -}); \ No newline at end of file +}); diff --git a/cypress/integration/common/I_get_removed_from_his_follower_collection.js b/cypress/support/step_definitions/common/I_get_removed_from_his_follower_collection.js similarity index 73% rename from cypress/integration/common/I_get_removed_from_his_follower_collection.js rename to cypress/support/step_definitions/common/I_get_removed_from_his_follower_collection.js index b32ca5961..7721efda0 100644 --- a/cypress/integration/common/I_get_removed_from_his_follower_collection.js +++ b/cypress/support/step_definitions/common/I_get_removed_from_his_follower_collection.js @@ -1,8 +1,8 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I get removed from his follower collection", () => { cy.get(".base-card") .not(".post-link"); cy.get(".main-container") .contains(".base-card","is not followed by anyone"); - }); \ No newline at end of file + }); diff --git a/cypress/integration/common/I_log_out.js b/cypress/support/step_definitions/common/I_log_out.js similarity index 81% rename from cypress/integration/common/I_log_out.js rename to cypress/support/step_definitions/common/I_log_out.js index 60185bc45..c97506535 100644 --- a/cypress/integration/common/I_log_out.js +++ b/cypress/support/step_definitions/common/I_log_out.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I log out", () => { cy.get(".avatar-menu").then(($menu) => { diff --git a/cypress/integration/common/I_navigate_to_my_{string}_settings_page.js b/cypress/support/step_definitions/common/I_navigate_to_my_{string}_settings_page.js similarity index 79% rename from cypress/integration/common/I_navigate_to_my_{string}_settings_page.js rename to cypress/support/step_definitions/common/I_navigate_to_my_{string}_settings_page.js index 4d369eab2..91a3b58d9 100644 --- a/cypress/integration/common/I_navigate_to_my_{string}_settings_page.js +++ b/cypress/support/step_definitions/common/I_navigate_to_my_{string}_settings_page.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I navigate to my {string} settings page", settingsPage => { cy.get(".avatar-menu-trigger").click(); @@ -7,4 +7,4 @@ When("I navigate to my {string} settings page", settingsPage => { .contains("Settings") .click(); cy.contains(".ds-menu-item-link", settingsPage).click(); -}); \ No newline at end of file +}); diff --git a/cypress/support/step_definitions/common/I_navigate_to_page_{string}.js b/cypress/support/step_definitions/common/I_navigate_to_page_{string}.js new file mode 100644 index 000000000..d90cc906c --- /dev/null +++ b/cypress/support/step_definitions/common/I_navigate_to_page_{string}.js @@ -0,0 +1,7 @@ +import { Given } from "@badeball/cypress-cucumber-preprocessor"; +import 'cypress-network-idle'; + +Given("I navigate to page {string}", page => { + cy.visit(page); + cy.waitForNetworkIdle(2000) +}); diff --git a/cypress/support/step_definitions/common/I_refresh_the_page.js b/cypress/support/step_definitions/common/I_refresh_the_page.js new file mode 100644 index 000000000..47e493fe4 --- /dev/null +++ b/cypress/support/step_definitions/common/I_refresh_the_page.js @@ -0,0 +1,6 @@ +import { When } from "@badeball/cypress-cucumber-preprocessor"; + +When('I refresh the page', () => { + cy.visit('/') + .reload(); +}); diff --git a/cypress/integration/common/I_search_for_{string}.js b/cypress/support/step_definitions/common/I_search_for_{string}.js similarity index 78% rename from cypress/integration/common/I_search_for_{string}.js rename to cypress/support/step_definitions/common/I_search_for_{string}.js index eaad481f7..f91959182 100644 --- a/cypress/integration/common/I_search_for_{string}.js +++ b/cypress/support/step_definitions/common/I_search_for_{string}.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("I search for {string}", value => { cy.intercept({ @@ -9,4 +9,4 @@ When("I search for {string}", value => { .focus() .type(value); cy.wait("@graphqlRequest"); -}); \ No newline at end of file +}); diff --git a/cypress/integration/common/I_see_a_toaster_with_status_{string}.js b/cypress/support/step_definitions/common/I_see_a_toaster_with_status_{string}.js similarity index 73% rename from cypress/integration/common/I_see_a_toaster_with_status_{string}.js rename to cypress/support/step_definitions/common/I_see_a_toaster_with_status_{string}.js index aa07d787c..c7bd91e29 100644 --- a/cypress/integration/common/I_see_a_toaster_with_status_{string}.js +++ b/cypress/support/step_definitions/common/I_see_a_toaster_with_status_{string}.js @@ -1,4 +1,4 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I see a toaster with status {string}", (status) => { switch (status) { @@ -6,4 +6,4 @@ Then("I see a toaster with status {string}", (status) => { cy.get(".iziToast.iziToast-color-green").should("be.visible"); break; } -}) \ No newline at end of file +}) diff --git a/cypress/integration/common/I_see_a_toaster_with_{string}.js b/cypress/support/step_definitions/common/I_see_a_toaster_with_{string}.js similarity index 61% rename from cypress/integration/common/I_see_a_toaster_with_{string}.js rename to cypress/support/step_definitions/common/I_see_a_toaster_with_{string}.js index 1cf7da285..e1496b8de 100644 --- a/cypress/integration/common/I_see_a_toaster_with_{string}.js +++ b/cypress/support/step_definitions/common/I_see_a_toaster_with_{string}.js @@ -1,5 +1,5 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I see a toaster with {string}", (title) => { cy.get(".iziToast-message").should("contain", title); -}) \ No newline at end of file +}) diff --git a/cypress/integration/common/I_see_a_{string}_message.js b/cypress/support/step_definitions/common/I_see_a_{string}_message.js similarity index 54% rename from cypress/integration/common/I_see_a_{string}_message.js rename to cypress/support/step_definitions/common/I_see_a_{string}_message.js index 6cc2cbf6b..cc8deca5f 100644 --- a/cypress/integration/common/I_see_a_{string}_message.js +++ b/cypress/support/step_definitions/common/I_see_a_{string}_message.js @@ -1,5 +1,5 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I see a {string} message:", (_type, message) => { cy.contains(message); -}); \ No newline at end of file +}); diff --git a/cypress/integration/common/I_should_see_the_following_posts_in_the_select_dropdown.js b/cypress/support/step_definitions/common/I_should_see_the_following_posts_in_the_select_dropdown.js similarity index 73% rename from cypress/integration/common/I_should_see_the_following_posts_in_the_select_dropdown.js rename to cypress/support/step_definitions/common/I_should_see_the_following_posts_in_the_select_dropdown.js index 420c3376a..88e18a280 100644 --- a/cypress/integration/common/I_should_see_the_following_posts_in_the_select_dropdown.js +++ b/cypress/support/step_definitions/common/I_should_see_the_following_posts_in_the_select_dropdown.js @@ -1,8 +1,8 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("I should see the following posts in the select dropdown:", table => { table.hashes().forEach(({ title }) => { cy.get(".ds-select-dropdown") .should("contain", title); }); -}); \ No newline at end of file +}); diff --git a/cypress/support/step_definitions/common/I_wait_for_{int}_milliseconds.js b/cypress/support/step_definitions/common/I_wait_for_{int}_milliseconds.js new file mode 100644 index 000000000..2ed462340 --- /dev/null +++ b/cypress/support/step_definitions/common/I_wait_for_{int}_milliseconds.js @@ -0,0 +1,5 @@ +import { When } from "@badeball/cypress-cucumber-preprocessor"; + +When("I wait for {int} milliseconds", time => { + cy.wait(time) +}); diff --git a/cypress/integration/common/the_checkbox_with_ID_{string}_should_{string}.js b/cypress/support/step_definitions/common/the_checkbox_with_ID_{string}_should_{string}.js similarity index 62% rename from cypress/integration/common/the_checkbox_with_ID_{string}_should_{string}.js rename to cypress/support/step_definitions/common/the_checkbox_with_ID_{string}_should_{string}.js index ad3f7f3cc..603524804 100644 --- a/cypress/integration/common/the_checkbox_with_ID_{string}_should_{string}.js +++ b/cypress/support/step_definitions/common/the_checkbox_with_ID_{string}_should_{string}.js @@ -1,4 +1,4 @@ -import { When } from "cypress-cucumber-preprocessor/steps"; +import { When } from "@badeball/cypress-cucumber-preprocessor"; When("the checkbox with ID {string} should {string}", (id, value) => { cy.get('#' + id).should(value) diff --git a/cypress/integration/common/the_first_post_on_the_newsfeed_has_the_title.js b/cypress/support/step_definitions/common/the_first_post_on_the_newsfeed_has_the_title.js similarity index 65% rename from cypress/integration/common/the_first_post_on_the_newsfeed_has_the_title.js rename to cypress/support/step_definitions/common/the_first_post_on_the_newsfeed_has_the_title.js index afe370e90..ba98a7a8e 100644 --- a/cypress/integration/common/the_first_post_on_the_newsfeed_has_the_title.js +++ b/cypress/support/step_definitions/common/the_first_post_on_the_newsfeed_has_the_title.js @@ -1,6 +1,6 @@ -import { Then } from "cypress-cucumber-preprocessor/steps"; +import { Then } from "@badeball/cypress-cucumber-preprocessor"; Then("the first post on the newsfeed has the title:", title => { cy.get(".post-teaser:first") .should("contain", title); -}); \ No newline at end of file +}); diff --git a/cypress/integration/common/the_following_{string}_are_in_the_database.js b/cypress/support/step_definitions/common/the_following_{string}_are_in_the_database.js similarity index 93% rename from cypress/integration/common/the_following_{string}_are_in_the_database.js rename to cypress/support/step_definitions/common/the_following_{string}_are_in_the_database.js index e03a705f4..8e41afa2a 100644 --- a/cypress/integration/common/the_following_{string}_are_in_the_database.js +++ b/cypress/support/step_definitions/common/the_following_{string}_are_in_the_database.js @@ -1,4 +1,4 @@ -import { Given } from "cypress-cucumber-preprocessor/steps"; +import { Given } from "@badeball/cypress-cucumber-preprocessor"; Given("the following {string} are in the database:", (table,data) => { switch(table){ @@ -37,4 +37,4 @@ Given("the following {string} are in the database:", (table,data) => { }); break } -}) \ No newline at end of file +}) diff --git a/cypress/integration/common/{string}_wrote_a_post_{string}.js b/cypress/support/step_definitions/common/{string}_wrote_a_post_{string}.js similarity index 68% rename from cypress/integration/common/{string}_wrote_a_post_{string}.js rename to cypress/support/step_definitions/common/{string}_wrote_a_post_{string}.js index 42ac98028..0da055951 100644 --- a/cypress/integration/common/{string}_wrote_a_post_{string}.js +++ b/cypress/support/step_definitions/common/{string}_wrote_a_post_{string}.js @@ -1,4 +1,4 @@ -import { Given } from "cypress-cucumber-preprocessor/steps"; +import { Given } from "@badeball/cypress-cucumber-preprocessor"; Given('{string} wrote a post {string}', (author, title) => { cy.factory() @@ -7,4 +7,4 @@ Given('{string} wrote a post {string}', (author, title) => { }, { authorId: author, }); -}); \ No newline at end of file +}); diff --git a/deployment/configurations/stage.ocelot.social b/deployment/configurations/stage.ocelot.social index be3ac7ad2..3056eec04 160000 --- a/deployment/configurations/stage.ocelot.social +++ b/deployment/configurations/stage.ocelot.social @@ -1 +1 @@ -Subproject commit be3ac7ad29f37d6a00fb3203db302cd91cebb9fa +Subproject commit 3056eec040cf7a052a5d08ab4cac7129355ab652 diff --git a/deployment/scripts/cluster.reseed.sh b/deployment/scripts/cluster.reseed.sh index 9aba0a353..4d544bfe8 100755 --- a/deployment/scripts/cluster.reseed.sh +++ b/deployment/scripts/cluster.reseed.sh @@ -15,4 +15,4 @@ echo "Using CONFIGURATION=${CONFIGURATION}" KUBECONFIG=${KUBECONFIG:-${SCRIPT_DIR}/../configurations/${CONFIGURATION}/kubeconfig.yaml} # clean & seed -kubectl --kubeconfig=${KUBECONFIG} -n default exec -it $(kubectl --kubeconfig=${KUBECONFIG} -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- /bin/sh -c "node --experimental-repl-await dist/db/clean.js && node --experimental-repl-await dist/db/seed.js" \ No newline at end of file +kubectl --kubeconfig=${KUBECONFIG} -n default exec -it $(kubectl --kubeconfig=${KUBECONFIG} -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- /bin/sh -c "node --experimental-repl-await build/db/clean.js && node --experimental-repl-await build/db/seed.js" \ No newline at end of file diff --git a/deployment/src/docker/backend.Dockerfile b/deployment/src/docker/backend.Dockerfile index 6d458c9d7..2d8132d0c 100644 --- a/deployment/src/docker/backend.Dockerfile +++ b/deployment/src/docker/backend.Dockerfile @@ -34,7 +34,7 @@ FROM $APP_IMAGE_BASE as branded # TODO - do all copying with one COPY command to have one layer # Copy "binary"-files from build image -COPY --from=build ${DOCKER_WORKDIR}/dist ./dist +COPY --from=build ${DOCKER_WORKDIR}/build ./build COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules # TODO - externalize the uploads so we can copy the whole folder COPY --from=build ${DOCKER_WORKDIR}/public/img/ ./public/img/ diff --git a/deployment/src/kubernetes/README.md b/deployment/src/kubernetes/README.md index 0f7ecd20f..1c0c8e2d8 100644 --- a/deployment/src/kubernetes/README.md +++ b/deployment/src/kubernetes/README.md @@ -293,7 +293,7 @@ $ kubectl -n default rollout status deployment/ocelot-neo4j --timeout=240s $ kubectl config get-contexts # reset and seed Neo4j database via backend for staging -$ kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- /bin/sh -c "node --experimental-repl-await dist/db/clean.js && node --experimental-repl-await dist/db/seed.js" +$ kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- /bin/sh -c "node --experimental-repl-await build/db/clean.js && node --experimental-repl-await build/db/seed.js" ``` diff --git a/package.json b/package.json index bc2cdfd62..b53319396 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ocelot-social", - "version": "2.6.0", + "version": "2.7.0", "description": "Free and open source software program code available to run social networks.", "author": "ocelot.social Community", "license": "MIT", @@ -15,25 +15,27 @@ "scripts": { "db:seed": "cd backend && yarn run db:seed", "db:reset": "cd backend && yarn run db:reset", - "cypress:run": "cypress run --browser electron --config-file ./cypress/cypress.json", - "cypress:open": "cypress open --browser electron --config-file ./cypress/cypress.json", + "cypress:run": "cypress run --browser electron --config-file ./cypress/cypress.config.js", + "cypress:open": "cypress open --browser electron --config-file ./cypress/cypress.config.js", "cucumber:setup": "cd backend && yarn run dev", "cucumber": "wait-on tcp:4000 && cucumber-js --require-module @babel/register --exit", "release": "yarn version --no-git-tag-version --no-commit-hooks --no-commit && auto-changelog --latest-version $(node -p -e \"require('./package.json').version\") && cd backend && yarn version --no-git-tag-version --no-commit-hooks --no-commit --new-version $(node -p -e \"require('./../package.json').version\") && cd ../webapp && yarn version --no-git-tag-version --no-commit-hooks --no-commit --new-version $(node -p -e \"require('./../package.json').version\") && cd ../webapp/maintenance/source && yarn version --no-git-tag-version --no-commit-hooks --no-commit --new-version $(node -p -e \"require('./../../../package.json').version\")" }, "devDependencies": { "@babel/core": "^7.21.8", - "@babel/preset-env": "^7.21.5", + "@babel/preset-env": "^7.22.4", "@babel/register": "^7.12.10", + "@badeball/cypress-cucumber-preprocessor": "^15.1.4", + "@cypress/browserify-preprocessor": "^3.0.2", "@faker-js/faker": "7.6.0", "auto-changelog": "^2.3.0", "bcryptjs": "^2.4.3", "cross-env": "^7.0.3", "cucumber": "^6.0.5", - "cypress": "^7.0.1", - "cypress-cucumber-preprocessor": "^2.2.1", + "cypress": "^12.6.0", "cypress-file-upload": "^3.5.3", - "date-fns": "^2.30.0", + "cypress-network-idle": "^1.14.2", + "date-fns": "^2.25.0", "dotenv": "^8.2.0", "expect": "^29.5.0", "graphql-request": "^2.0.0", diff --git a/webapp/.nvmrc b/webapp/.nvmrc index cb77acbfe..58b8c2a00 100644 --- a/webapp/.nvmrc +++ b/webapp/.nvmrc @@ -1 +1 @@ -v19.4.0 \ No newline at end of file +v20.2.0 \ No newline at end of file diff --git a/webapp/assets/_new/styles/tokens.scss b/webapp/assets/_new/styles/tokens.scss index 863e0e0b7..22e0214ff 100644 --- a/webapp/assets/_new/styles/tokens.scss +++ b/webapp/assets/_new/styles/tokens.scss @@ -90,6 +90,9 @@ $background-color-primary-inverse: rgb(241, 253, 244); $background-color-secondary: rgb(0, 142, 230); $background-color-secondary-active: rgb(10, 161, 255); $background-color-secondary-inverse: rgb(240, 249, 255); +$background-color-third: rgb(126, 82, 204); +$background-color-third-active: rgb(160, 103, 255); +$background-color-third-inverse: rgb(239, 230, 255); $background-color-success: rgb(23, 181, 63); $background-color-success-active: rgb(26, 203, 71); $background-color-success-inverse: rgb(241, 253, 244); @@ -395,3 +398,12 @@ $color-toast-orange: $color-warning; $color-toast-yellow: $color-yellow; $color-toast-blue: $color-secondary; $color-toast-green: $color-success; + +/** + * @tokens Ribbon Color + */ + +$color-ribbon-event: $background-color-third; +$color-ribbon-event-active: $background-color-third-active; +$color-ribbon-article: $background-color-secondary; +$color-ribbon-article-active: $background-color-secondary-active; \ No newline at end of file diff --git a/webapp/components/ContributionForm/ContributionForm.spec.js b/webapp/components/ContributionForm/ContributionForm.spec.js index 6b9db448b..9095665fc 100644 --- a/webapp/components/ContributionForm/ContributionForm.spec.js +++ b/webapp/components/ContributionForm/ContributionForm.spec.js @@ -1,8 +1,8 @@ import { mount } from '@vue/test-utils' import ContributionForm from './ContributionForm.vue' +import PostMutations from '~/graphql/PostMutations.js' import Vuex from 'vuex' -import PostMutations from '~/graphql/PostMutations.js' import ImageUploader from '~/components/Uploader/ImageUploader' import MutationObserver from 'mutation-observer' @@ -108,6 +108,10 @@ describe('ContributionForm.vue', () => { await wrapper.vm.updateEditorContent(postContent) }) + it('has no event data block', () => { + expect(wrapper.find('div.eventDatas').exists()).toBe(false) + }) + it('title cannot be empty', async () => { postTitleInput.setValue('') wrapper.find('form').trigger('submit') @@ -293,5 +297,88 @@ describe('ContributionForm.vue', () => { }) }) }) + + describe('Events', () => { + beforeEach(() => { + propsData.createEvent = true + wrapper = Wrapper() + }) + + it('has event data block', () => { + expect(wrapper.find('div.eventDatas').exists()).toBe(true) + }) + + describe('is online event', () => { + it('has false as default', () => { + expect(wrapper.vm.formData.eventIsOnline).toBe(false) + }) + + it('has input for event location', () => { + expect(wrapper.find('input[name="eventLocationName"]').exists()).toBe(true) + }) + + describe('click is online event', () => { + beforeEach(() => { + wrapper.find('input[name="eventIsOnline"]').setChecked(true) + }) + + it('has no input for event location', () => { + expect(wrapper.find('input[name="eventLocationName"]').exists()).toBe(false) + }) + }) + + describe('invalid form', () => { + beforeEach(() => { + wrapper.find('input[name="title"]').setValue('Illegaler Kindergeburtstag') + wrapper.vm.updateEditorContent('Elli hat Geburtstag!') + }) + + it('has submit button disabled', () => { + expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBe('disabled') + }) + }) + + describe('valid form', () => { + const now = new Date() + + beforeEach(() => { + wrapper.find('input[name="title"]').setValue('Illegaler Kindergeburtstag') + wrapper.vm.updateEditorContent('Elli hat Geburtstag!') + wrapper + .findComponent({ name: 'DatePicker' }) + .vm.$emit('change', new Date(now.getFullYear(), now.getMonth() + 1).toISOString()) + wrapper.find('input[name="eventVenue"]').setValue('Ellis Kinderzimmer') + wrapper.find('input[name="eventLocationName"]').setValue('Deutschland') + }) + + it('has submit button not disabled', () => { + expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBe(undefined) + }) + + describe('submit', () => { + beforeEach(() => { + wrapper.find('form').trigger('submit') + }) + + it('calls create post', () => { + expect(mocks.$apollo.mutate).toHaveBeenCalledWith({ + mutation: PostMutations().CreatePost, + variables: expect.objectContaining({ + title: 'Illegaler Kindergeburtstag', + content: 'Elli hat Geburtstag!', + eventInput: { + eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(), + eventVenue: 'Ellis Kinderzimmer', + eventLocationName: 'Deutschland', + eventIsOnline: false, + eventEnd: null, + }, + }), + }) + }) + }) + }) + }) + }) }) }) diff --git a/webapp/components/ContributionForm/ContributionForm.vue b/webapp/components/ContributionForm/ContributionForm.vue index 997a25341..0067dab72 100644 --- a/webapp/components/ContributionForm/ContributionForm.vue +++ b/webapp/components/ContributionForm/ContributionForm.vue @@ -54,13 +54,13 @@ -
+

- + -
+
-
+
- +
- + - - + +
@@ -113,10 +116,10 @@
- +
@@ -131,9 +134,11 @@
{{ $t('post.viewEvent.eventIsOnline') }}
@@ -153,7 +158,7 @@ - + null, }, - creatEvent: { + createEvent: { type: Boolean, default: false, }, @@ -252,24 +257,6 @@ export default { eventVenue: eventVenue || '', eventIsOnline: eventIsOnline || false, }, - formSchema: { - title: { required: true, min: 3, max: 100 }, - content: { required: true }, - imageBlurred: { required: false }, - categoryIds: { - type: 'array', - required: this.categoriesActive, - validator: (_, value = []) => { - if (this.categoriesActive && (value.length === 0 || value.length > 3)) { - return [new Error(this.$t('common.validations.categories'))] - } - return [] - }, - }, - eventStart: { required: !!this.creatEvent }, - eventVenue: { required: !!this.creatEvent, min: 3, max: 100 }, - eventLocationName: { required: !!this.creatEvent, min: 3, max: 100 }, - }, loading: false, users: [], hashtags: [], @@ -283,14 +270,69 @@ export default { ...mapGetters({ currentUser: 'auth/user', }), + formSchema() { + return { + title: { required: true, min: 3, max: 100 }, + content: { required: true }, + imageBlurred: { required: false }, + categoryIds: { + type: 'array', + required: this.categoriesActive, + validator: (_, value = []) => { + if (this.categoriesActive && (value.length === 0 || value.length > 3)) { + return [new Error(this.$t('common.validations.categories'))] + } + return [] + }, + }, + eventStart: { required: !!this.createEvent }, + eventVenue: { + required: !!this.createEvent, + min: 3, + max: 100, + validator: (_, value = '') => { + if (!this.createEvent) return [] + if (!value.trim()) { + return [new Error(this.$t('common.validations.eventVenueNotEmpty'))] + } + if (value.length < 3 || value.length > 100) { + return [ + new Error(this.$t('common.validations.eventVenueLength', { min: 3, max: 100 })), + ] + } + return [] + }, + }, + eventLocationName: { + required: !!this.createEvent && !this.formData.eventIsOnline, + min: 3, + max: 100, + validator: (_, value = '') => { + if (!this.createEvent) return [] + if (this.formData.eventIsOnline) return [] + if (!value.trim()) { + return [new Error(this.$t('common.validations.eventLocationNameNotEmpty'))] + } + if (value.length < 3 || value.length > 100) { + return [ + new Error( + this.$t('common.validations.eventLocationNameLength', { min: 3, max: 100 }), + ), + ] + } + return [] + }, + }, + } + }, eventInput() { - if (this.creatEvent) { + if (this.createEvent) { return { eventStart: this.formData.eventStart, eventVenue: this.formData.eventVenue, eventEnd: this.formData.eventEnd, eventIsOnline: this.formData.eventIsOnline, - eventLocationName: this.formData.eventLocationName, + eventLocationName: !this.formData.eventIsOnline ? this.formData.eventLocationName : null, } } return undefined @@ -310,6 +352,9 @@ export default { groupCategories() { return this.group && this.group.categories }, + showEventLocationName() { + return !this.formData.eventIsOnline + }, }, watch: { groupCategories() { @@ -356,7 +401,7 @@ export default { id: this.contribution.id || null, image, groupId: this.groupId, - postType: !this.creatEvent ? 'Article' : 'Event', + postType: !this.createEvent ? 'Article' : 'Event', eventInput: this.eventInput, }, }) @@ -378,6 +423,15 @@ export default { updateEditorContent(value) { this.$refs.contributionForm.update('content', value) }, + changeEventIsOnline(event) { + this.$refs.contributionForm.update('eventIsOnline', this.formData.eventIsOnline) + }, + changeEventEnd(event) { + this.$refs.contributionForm.update('eventEnd', event) + }, + changeEventStart(event) { + this.$refs.contributionForm.update('eventStart', event) + }, addHeroImage(file) { this.formData.image = null if (file) { @@ -443,6 +497,24 @@ export default { margin-top: -10px; } } + // style override to handle dynamic inputs + .event-location-grid { + grid-template-columns: repeat(2, 1fr) !important; + } + + .event-grid-item { + // important needed because of component inline style + grid-row-end: span 3 !important; + } + .event-grid-item-z-helper { + z-index: 20; + } + .event-grid-item-margin-helper { + margin-top: 10px; + } + .event-grid-item-font-helper { + font-size: larger; + } } .contribution-form > .base-card { @@ -491,6 +563,12 @@ export default { min-width: fit-content; } } + + > .buttons-footer-helper { + margin-right: 16px; + // important needed because of component inline style + margin-bottom: 6px !important; + } } .blur-toggle { diff --git a/webapp/components/DateTimeRange/DateTimeRange.vue b/webapp/components/DateTimeRange/DateTimeRange.vue new file mode 100644 index 000000000..de9b442c5 --- /dev/null +++ b/webapp/components/DateTimeRange/DateTimeRange.vue @@ -0,0 +1,101 @@ + + + + + diff --git a/webapp/components/FilterMenu/CategoriesFilter.vue b/webapp/components/FilterMenu/CategoriesFilter.vue index 8b96245fd..347994c9a 100644 --- a/webapp/components/FilterMenu/CategoriesFilter.vue +++ b/webapp/components/FilterMenu/CategoriesFilter.vue @@ -12,12 +12,12 @@
  • -
    - + + diff --git a/webapp/components/FilterMenu/FilterMenu.spec.js b/webapp/components/FilterMenu/FilterMenu.spec.js index c3a3ca113..30f970b62 100644 --- a/webapp/components/FilterMenu/FilterMenu.spec.js +++ b/webapp/components/FilterMenu/FilterMenu.spec.js @@ -15,6 +15,7 @@ describe('FilterMenu.vue', () => { const getters = { 'posts/isActive': () => false, + 'posts/filteredPostTypes': () => [], 'posts/orderBy': () => 'createdAt_desc', } diff --git a/webapp/components/FilterMenu/FilterMenuComponent.vue b/webapp/components/FilterMenu/FilterMenuComponent.vue index 708c3bc7c..9a52a9b98 100644 --- a/webapp/components/FilterMenu/FilterMenuComponent.vue +++ b/webapp/components/FilterMenu/FilterMenuComponent.vue @@ -6,6 +6,10 @@
    +
    +

    {{ $t('filter-menu.eventsBy') }}

    + +

    {{ $t('filter-menu.order-by') }}

    @@ -14,6 +18,8 @@ diff --git a/webapp/components/FilterMenu/HeaderButton.vue b/webapp/components/FilterMenu/HeaderButton.vue index 780e29ade..dfacff43f 100644 --- a/webapp/components/FilterMenu/HeaderButton.vue +++ b/webapp/components/FilterMenu/HeaderButton.vue @@ -44,13 +44,12 @@ export default { diff --git a/webapp/components/Notification/Notification.vue b/webapp/components/Notification/Notification.vue index a9cd75f4e..9b70da794 100644 --- a/webapp/components/Notification/Notification.vue +++ b/webapp/components/Notification/Notification.vue @@ -9,7 +9,7 @@

    {{ $t(`notifications.reason.${notification.reason}`) }}

    diff --git a/webapp/components/PostTeaser/PostTeaser.vue b/webapp/components/PostTeaser/PostTeaser.vue index 604fb121f..d852d9e23 100644 --- a/webapp/components/PostTeaser/PostTeaser.vue +++ b/webapp/components/PostTeaser/PostTeaser.vue @@ -11,7 +11,6 @@ }" :highlight="isPinned" > - @@ -31,25 +30,19 @@ margin-bottom="small" style="padding: 5px" > - - - - - - {{ $t('post.viewEvent.eventIsOnline') }} - - - {{ post.eventLocationName }} - - - - - - - {{ getEventDateString }} - - - + + @@ -113,12 +106,13 @@ import Category from '~/components/Category' import ContentMenu from '~/components/ContentMenu/ContentMenu' import CounterIcon from '~/components/_new/generic/CounterIcon/CounterIcon' +import DateTimeRange from '~/components/DateTimeRange/DateTimeRange' import HcRibbon from '~/components/Ribbon' +import LocationTeaser from '~/components/LocationTeaser/LocationTeaser' import UserTeaser from '~/components/UserTeaser/UserTeaser' import { mapGetters } from 'vuex' import PostMutations from '~/graphql/PostMutations' import { postMenuModalsData, deletePostMutation } from '~/components/utils/PostHelpers' -import { format } from 'date-fns' export default { name: 'PostTeaser', @@ -126,7 +120,9 @@ export default { Category, ContentMenu, CounterIcon, + DateTimeRange, HcRibbon, + LocationTeaser, UserTeaser, }, props: { @@ -185,15 +181,6 @@ export default { if (this.post.postType[0] === 'Event') return this.$t('post.event') return this.$t('post.name') }, - getEventDateString() { - if (this.post.eventEnd) { - const eventStart = format(new Date(this.post.eventStart), 'dd.MM.') - const eventEnd = format(new Date(this.post.eventEnd), 'dd.MM.yyyy') - return `${eventStart} - ${eventEnd}` - } else { - return format(new Date(this.post.eventStart), 'dd.MM.yyyy') - } - }, }, methods: { async deletePostCallback() { @@ -228,6 +215,7 @@ export default { }, } + diff --git a/webapp/graphql/PostMutations.js b/webapp/graphql/PostMutations.js index 6b71b86b9..c3a9369c3 100644 --- a/webapp/graphql/PostMutations.js +++ b/webapp/graphql/PostMutations.js @@ -61,6 +61,8 @@ export default () => { $content: String! $image: ImageInput $categoryIds: [ID] + $postType: PostType + $eventInput: _EventInput ) { UpdatePost( id: $id @@ -68,6 +70,8 @@ export default () => { content: $content image: $image categoryIds: $categoryIds + postType: $postType + eventInput: $eventInput ) { id title @@ -85,6 +89,14 @@ export default () => { name role } + postType + eventStart + eventLocationName + eventVenue + eventLocation { + lng + lat + } } } `, diff --git a/webapp/jest.config.js b/webapp/jest.config.js index b38b05ecd..e9185f60e 100644 --- a/webapp/jest.config.js +++ b/webapp/jest.config.js @@ -20,9 +20,10 @@ module.exports = { lines: 83, }, }, + coverageProvider: 'v8', setupFiles: ['/test/registerContext.js', '/test/testSetup.js'], transform: { - '.*\\.(vue)$': 'vue-jest', + '.*\\.(vue)$': '@vue/vue2-jest', '^.+\\.js$': 'babel-jest', }, testMatch: ['**/?(*.)+(spec|test).js?(x)'], diff --git a/webapp/locales/de.json b/webapp/locales/de.json index 82b7c7bd4..29448fa10 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -115,11 +115,20 @@ "validations": { "categories": "es müssen eine bis drei Themen ausgewählt werden", "email": "muss eine gültige E-Mail-Adresse sein", + "eventLocationNameLength": "Minimum {min}, Maximum {max} Zeichen", + "eventLocationNameNotEmpty": "es dürfen nicht nur Freizeichen eingetragen werden", + "eventVenueLength": "Minimum {min}, Maximum {max} Zeichen", + "eventVenueNotEmpty": "es dürfen nicht nur Freizeichen eingetragen werden", "url": "muss eine gültige URL sein" }, "versus": "Versus" }, "components": { + "dateTimeRange": { + "hourMinute": "HH:mm", + "monthDay": "dd.MM.", + "yearMonthDay": "dd.MM.yyyy" + }, "password-reset": { "change-password": { "error": "Passwort Änderung fehlgeschlagen. Möglicherweise falscher Sicherheitscode?", @@ -272,7 +281,9 @@ "myFriends": "Nutzer denen ich folge", "myGroups": "Aus meinen Gruppen", "myTopics": "Meine Themen", - "noFilter": "Beiträge filtern" + "noFilter": "Inhalt filtern", + "onlyArticles": "Nur Beiträge", + "onlyEvents": "Nur Veranstaltungen" }, "filterMyGroups": "Beiträge in meinen Gruppen", "inappropriatePicture": "Dieses Bild kann für einige Menschen unangemessen sein.", @@ -378,31 +389,53 @@ }, "filter-menu": { "all": "Alle", - "article": "Artikel", + "article": "Beitrag", "categories": "Themen", + "creationDate": "Erstellungszeitpunkt", "deleteFilter": "Filter löschen", "emotions": "Emotionen", - "events": "Veranstaltungen", + "ended": { + "all": { + "hint": "Zeige alle, auch beendete", + "label": "Alle" + }, + "onlyEnded": { + "hint": "Zeige nur noch nicht beendete", + "label": "Nicht beendete" + } + }, + "event": "Veranstaltung", + "eventsBy": "Veranstaltungen – zeige ...", + "eventsEnded": "Beendet", "filter-by": "Filtern nach ...", "following": "Nutzer denen ich folge", "languages": "Sprachen", "my-groups": "Meinen Gruppen", "order": { + "last": { + "hint": "Sortiere die Letzten nach vorn", + "label": "Letzte zuerst" + }, "newest": { "hint": "Sortiere die Neuesten nach vorn", "label": "Neueste zuerst" }, + "next": { + "hint": "Sortiere die Nächsten nach vorn", + "label": "Nächste zuerst" + }, "oldest": { "hint": "Sortiere die Ältesten nach vorn", "label": "Älteste zuerst" } }, "order-by": "Sortieren nach ...", - "post-type": "Beitrags-Typ", + "post-type": "Inhaltstyp", "save": { "error": "Themen konnten nicht gespeichert werden!", "success": "Themen gespeichert!" - } + }, + "startDate": "Anfangszeitpunkt" }, "followButton": { "follow": "Folgen", @@ -702,6 +735,7 @@ }, "edited": "bearbeitet", "editPost": { + "event": "Bearbeite deine Veranstaltung", "forGroup": { "title": "Für die Gruppe „{name}“" }, @@ -723,7 +757,7 @@ }, "viewEvent": { "eventEnd": "Ende", - "eventIsOnline": "Online Veranstaltung", + "eventIsOnline": "Online", "eventLocationName": "Stadt", "eventStart": "Beginn", "eventVenue": "Veranstaltungsort", diff --git a/webapp/locales/en.json b/webapp/locales/en.json index 45a241957..13a040d36 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -115,11 +115,20 @@ "validations": { "categories": "at least one and at most three topics must be selected", "email": "must be a valid e-mail address", + "eventLocationNameLength": "minimum {min} or maximum {max} characters", + "eventLocationNameNotEmpty": "only empty characters are not allowed", + "eventVenueLength": "minimum {min} or maximum {max} characters", + "eventVenueNotEmpty": "only empty characters are not allowed", "url": "must be a valid URL" }, "versus": "Versus" }, "components": { + "dateTimeRange": { + "hourMinute": "HH:mm", + "monthDay": "MM/dd/", + "yearMonthDay": "MM/dd/yyyy" + }, "password-reset": { "change-password": { "error": "Changing your password failed. Maybe the security code was not correct?", @@ -272,7 +281,9 @@ "myFriends": "Users I follow", "myGroups": "By my groups", "myTopics": "My topics", - "noFilter": "Filter posts" + "noFilter": "Filter content", + "onlyArticles": "Only articles", + "onlyEvents": "Only events" }, "filterMyGroups": "Contributions in my groups", "inappropriatePicture": "This image may be inappropriate for some people.", @@ -380,29 +391,51 @@ "all": "All", "article": "Article", "categories": "Topics", + "creationDate": "Creation date", "deleteFilter": "Delete filter", "emotions": "Emotions", - "events": "Events", + "ended": { + "all": { + "hint": "Show all, also ended", + "label": "All" + }, + "onlyEnded": { + "hint": "Show only not ended", + "label": "Not ended" + } + }, + "event": "Event", + "eventsBy": "Events – show ...", + "eventsEnded": "Ended", "filter-by": "Filter by ...", "following": "Users I follow", "languages": "Languages", "my-groups": "My groups", "order": { + "last": { + "hint": "Sort posts by the last first", + "label": "Last first" + }, "newest": { "hint": "Sort posts by the newest first", "label": "Newest first" }, + "next": { + "hint": "Sort posts by the next first", + "label": "Next first" + }, "oldest": { "hint": "Sort posts by the oldest first", "label": "Oldest first" } }, "order-by": "Order by ...", - "post-type": "Post type", + "post-type": "Content type", "save": { "error": "Failed saving topic settings!", "success": "Topics saved!" - } + }, + "startDate": "Start date" }, "followButton": { "follow": "Follow", @@ -698,10 +731,11 @@ "forGroup": { "title": "For The Group “{name}”" }, - "title": "Create A New Post" + "title": "Create A New Article" }, "edited": "edited", "editPost": { + "event": "Edit Your Event", "forGroup": { "title": "For The Group “{name}”" }, @@ -716,14 +750,14 @@ "unpin": "Unpin post", "unpinnedSuccessfully": "Post unpinned successfully!" }, - "name": "Post", + "name": "Article", "pinned": "Announcement", "takeAction": { "name": "Take action" }, "viewEvent": { "eventEnd": "End", - "eventIsOnline": "Online Event", + "eventIsOnline": "Online", "eventLocationName": "City", "eventStart": "Start", "eventVenue": "Venue", diff --git a/webapp/maintenance/source/package.json b/webapp/maintenance/source/package.json index 48b6f7d29..ad3a60e76 100644 --- a/webapp/maintenance/source/package.json +++ b/webapp/maintenance/source/package.json @@ -1,6 +1,6 @@ { "name": "@ocelot-social/maintenance", - "version": "2.6.0", + "version": "2.7.0", "description": "Maintenance page for ocelot.social", "repository": "https://github.com/Ocelot-Social-Community/Ocelot-Social", "author": "ocelot.social Community", diff --git a/webapp/package.json b/webapp/package.json index 9c0b91155..cd748c56f 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -1,6 +1,6 @@ { "name": "ocelot-social-webapp", - "version": "2.6.0", + "version": "2.7.0", "description": "ocelot.social Frontend", "repository": "https://github.com/Ocelot-Social-Community/Ocelot-Social", "author": "ocelot.social Community", @@ -66,9 +66,9 @@ "zxcvbn": "^4.4.2" }, "devDependencies": { - "@babel/core": "~7.21.4", + "@babel/core": "~7.22.1", "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/preset-env": "^7.20.2", + "@babel/preset-env": "^7.22.4", "@faker-js/faker": "5.1.0", "@nuxtjs/composition-api": "0.32.0", "@storybook/addon-a11y": "^6.3.6", @@ -79,8 +79,9 @@ "@vue/eslint-config-prettier": "~6.0.0", "@vue/server-test-utils": "~1.0.0-beta.31", "@vue/test-utils": "1.3.4", + "@vue/vue2-jest": "29", "async-validator": "^3.2.4", - "babel-core": "~7.0.0-bridge.0", + "babel-core": "^7.0.0-bridge.0", "babel-eslint": "~10.1.0", "babel-jest": "29.5", "babel-loader": "~8.1.0", @@ -110,7 +111,6 @@ "storybook-vue-router": "^1.0.7", "style-loader": "~0.23.1", "style-resources-loader": "~1.3.3", - "vue-jest": "~3.0.5", "vue-svg-loader": "~0.16.0", "vue-template-compiler": "^2.6.11" }, diff --git a/webapp/pages/groups.vue b/webapp/pages/groups.vue index 6b895de72..52366d0af 100644 --- a/webapp/pages/groups.vue +++ b/webapp/pages/groups.vue @@ -78,7 +78,7 @@ export default { Group: [], groupFilter: { isMember: true }, tabActive: 'myGroups', - pageSize: 5, + pageSize: 6, activePage: 0, myGroupsCount: 0, allGroupsCount: 0, diff --git a/webapp/pages/index.spec.js b/webapp/pages/index.spec.js index 8e55fada1..c16560a84 100644 --- a/webapp/pages/index.spec.js +++ b/webapp/pages/index.spec.js @@ -28,6 +28,10 @@ describe('PostIndex', () => { store = new Vuex.Store({ getters: { 'posts/filter': () => ({}), + 'posts/filteredPostTypes': () => [], + 'posts/articleSetInPostTypeFilter': () => false, + 'posts/eventSetInPostTypeFilter': () => false, + 'posts/eventsEnded': () => '', 'posts/orderBy': () => 'createdAt_desc', 'auth/user': () => { return { id: 'u23' } diff --git a/webapp/pages/index.vue b/webapp/pages/index.vue index 591da3300..7b5c4a903 100644 --- a/webapp/pages/index.vue +++ b/webapp/pages/index.vue @@ -25,6 +25,7 @@ + + + +
    -
    +
    @@ -120,6 +137,7 @@ + diff --git a/webapp/pages/post/edit/_id.spec.js b/webapp/pages/post/edit/_id.spec.js index aa25eb8e8..2773483a4 100644 --- a/webapp/pages/post/edit/_id.spec.js +++ b/webapp/pages/post/edit/_id.spec.js @@ -29,7 +29,12 @@ describe('post/_id.vue', () => { defaultClient: { query: jest.fn().mockResolvedValue({ data: { - Post: [{ author: { id: authorId } }], + Post: [ + { + author: { id: authorId }, + postType: ['Article'], + }, + ], }, }), }, diff --git a/webapp/pages/post/edit/_id.vue b/webapp/pages/post/edit/_id.vue index d365709be..04d120c50 100644 --- a/webapp/pages/post/edit/_id.vue +++ b/webapp/pages/post/edit/_id.vue @@ -1,7 +1,13 @@