Merge branch 'master' of github.com:Ocelot-Social-Community/Ocelot-Social into dependabot/npm_and_yarn/backend/nodemailer-html-to-text-3.2.0

This commit is contained in:
Wolfgang Huß 2021-09-14 12:34:55 +02:00
commit 8e321fb9b3
116 changed files with 2142 additions and 37708 deletions

View File

@ -4,8 +4,69 @@ 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).
#### [v1.0.4](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/1.0.3...v1.0.4)
#### [1.0.5](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/1.0.4...1.0.5)
- feat: 🍰 Landing Page And Other Internal Pages [`#4599`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4599)
- Bump eslint-plugin-prettier from 3.1.4 to 3.4.0 in /webapp [`#4577`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4577)
- Bump vue-scrollto from 2.17.1 to 2.20.0 in /webapp [`#4592`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4592)
- Bump date-fns from 2.22.1 to 2.23.0 [`#4596`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4596)
- Bump metascraper-description from 5.11.6 to 5.23.1 in /backend [`#4593`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4593)
- Bump slug from 2.1.1 to 5.1.0 [`#4525`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4525)
- Bump metascraper-lang from 5.11.8 to 5.23.1 in /backend [`#4587`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4587)
- Bump eslint-plugin-promise from 4.2.1 to 4.3.1 in /backend [`#4591`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4591)
- fix: 🍰 Quick Fix For backend Tests [`#4565`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4565)
- Bump eslint-config-prettier from 6.10.1 to 6.15.0 in /backend [`#4583`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4583)
- Bump subscriptions-transport-ws from 0.9.16 to 0.9.19 in /backend [`#4584`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4584)
- Bump metascraper-youtube from 5.11.8 to 5.23.0 in /backend [`#4579`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4579)
- Bump metascraper-publisher from 5.11.8 to 5.23.0 in /backend [`#4578`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4578)
- [Security] Bump node-notifier from 6.0.0 to 8.0.2 in /webapp [`#4299`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4299)
- Bump @storybook/addon-a11y from 5.3.21 to 6.3.6 in /webapp [`#4570`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4570)
- Bump metascraper-soundcloud from 5.11.8 to 5.23.0 in /backend [`#4576`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4576)
- Bump cross-env from 7.0.2 to 7.0.3 in /backend [`#4522`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4522)
- [Security] Bump browserslist from 4.9.1 to 4.16.6 in /backend [`#4444`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4444)
- 🍰 feat: Landing Page etc. [`#4555`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4555)
- [Security] Bump browserslist from 4.14.7 to 4.16.6 [`#4440`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4440)
- Bump auto-changelog from 2.2.1 to 2.3.0 [`#4515`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4515)
- Bump @storybook/vue from 5.3.21 to 6.3.6 in /webapp [`#4571`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4571)
- Bump @storybook/addon-actions from 5.3.18 to 5.3.21 in /webapp [`#4141`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4141)
- [Security] Bump ssri from 6.0.1 to 6.0.2 in /webapp [`#4390`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4390)
- [Security] Bump y18n from 4.0.0 to 4.0.3 in /backend [`#4356`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4356)
- Bump v-tooltip from 2.0.3 to 2.1.3 in /webapp [`#4308`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4308)
- Bump eslint-plugin-jest from 24.1.10 to 24.4.0 in /webapp [`#4564`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4564)
- Bump apollo-cache-inmemory from 1.6.5 to 1.6.6 in /webapp [`#4140`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4140)
- [Security] Bump websocket-extensions from 0.1.3 to 0.1.4 in /webapp [`#3975`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/3975)
- Bump linkify-it from 2.2.0 to 3.0.2 in /webapp [`#4139`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4139)
- [Security] Bump yargs-parser from 18.1.1 to 18.1.3 in /backend [`#3962`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/3962)
- [Security] Bump y18n from 3.2.1 to 3.2.2 in /webapp [`#4317`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4317)
- Bump vue-sweetalert-icons from 4.2.0 to 4.3.0 in /webapp [`#4142`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4142)
- Bump mustache from 4.0.1 to 4.2.0 in /backend [`#4310`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4310)
- [Security] Bump elliptic from 6.5.3 to 6.5.4 in /webapp [`#4286`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4286)
- [Security] Bump elliptic from 6.5.3 to 6.5.4 [`#4285`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4285)
- Bump neode from 0.3.7 to 0.4.7 [`#4162`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4162)
- Bump date-fns from 2.11.1 to 2.22.1 in /backend [`#4523`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4523)
- Bump stack-utils from 2.0.1 to 2.0.3 in /webapp [`#4076`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4076)
- Bump date-fns from 2.12.0 to 2.22.1 [`#4455`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4455)
- Bump date-fns from 2.12.0 to 2.22.1 in /webapp [`#4537`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4537)
- Bump cross-env from 7.0.2 to 7.0.3 [`#4032`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4032)
- Bump graphql-request from 1.8.2 to 2.0.0 [`#3988`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/3988)
- Bump cookie-universal-nuxt from 2.1.4 to 2.1.5 in /webapp [`#4561`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4561)
- Bump graphql from 14.6.0 to 14.7.0 in /webapp [`#4000`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4000)
- Bump prettier from 2.2.0 to 2.3.2 in /backend [`#4530`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4530)
- Bump merge-graphql-schemas from 1.7.7 to 1.7.8 in /backend [`#3959`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/3959)
- fix: 🍰 Fix Menu Legend Menu Bar Button Without Click Event [`#4556`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4556)
- Bump eslint-plugin-promise from 4.2.1 to 4.3.1 in /webapp [`#4534`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4534)
- feat: 🍰 Post Editor Legend [`#4492`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4492)
- New Issue type EPIC [`#4536`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4536)
- Upgrade to GitHub-native Dependabot [`#4399`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4399)
- Remove superfluous package-lock.json [`c7e4e6d`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/c7e4e6d2b26d448b3d2787aff4a0bde32c24e919)
- Delete superfluous and always conflicting file package-lock.json [`9932796`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/9932796d233789c76b917de533ec2efc99f6aa4a)
- Refactor pageParams, second step [`e8a0a5d`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/e8a0a5d13c0610066c50c98d5e0d661ee8139217)
#### [1.0.4](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/1.0.3...1.0.4)
> 8 June 2021
- chore: 🍰 Release v1.0.4 [`#4475`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4475)
- fixed wrong env variable [`#4474`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4474)
- chore: [WIP] 🍰 New Deployment With 'base' And 'code' Docker Images [`#4452`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4452)
- feat: 🍰 Flexible Footer Links [`#4468`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4468)

View File

@ -9,4 +9,3 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -74,7 +74,7 @@ Docker is a software development container tool that combines software and its d
#### General Installation of Docker
There are [sevaral ways to install Docker CE](https://docs.docker.com/install/) on your computer or server.
There are [several ways to install Docker CE](https://docs.docker.com/install/) on your computer or server.
* [install Docker Desktop on macOS](https://docs.docker.com/docker-for-mac/install/)
* [install Docker Desktop on Windows](https://docs.docker.com/docker-for-windows/install/)

View File

@ -1,6 +1,6 @@
{
"name": "ocelot-social-backend",
"version": "1.0.4",
"version": "1.0.5",
"description": "GraphQL Backend for ocelot.social",
"repository": "https://github.com/Ocelot-Social-Community/Ocelot-Social",
"author": "ocelot.social Community",
@ -61,7 +61,7 @@
"bcryptjs": "~2.4.3",
"cheerio": "~1.0.0-rc.3",
"cors": "~2.8.5",
"cross-env": "~7.0.2",
"cross-env": "~7.0.3",
"date-fns": "2.22.1",
"debug": "~4.1.1",
"dotenv": "~8.2.0",
@ -87,17 +87,17 @@
"metascraper-author": "^5.14.22",
"metascraper-clearbit-logo": "^5.3.0",
"metascraper-date": "^5.11.8",
"metascraper-description": "^5.11.6",
"metascraper-description": "^5.23.1",
"metascraper-image": "^5.11.8",
"metascraper-lang": "^5.11.8",
"metascraper-lang": "^5.23.1",
"metascraper-lang-detector": "^4.10.2",
"metascraper-logo": "^5.14.26",
"metascraper-publisher": "^5.11.8",
"metascraper-soundcloud": "^5.11.8",
"metascraper-publisher": "^5.23.0",
"metascraper-soundcloud": "^5.23.0",
"metascraper-title": "^5.11.8",
"metascraper-url": "^5.14.26",
"metascraper-video": "^5.11.8",
"metascraper-youtube": "^5.11.8",
"metascraper-youtube": "^5.23.0",
"migrate": "^1.7.0",
"mime-types": "^2.1.26",
"minimatch": "^3.0.4",
@ -112,7 +112,7 @@
"request": "~2.88.2",
"sanitize-html": "~1.22.0",
"slug": "~4.0.2",
"subscriptions-transport-ws": "^0.9.16",
"subscriptions-transport-ws": "^0.9.19",
"trunc-html": "~1.1.2",
"uuid": "~8.3.2",
"validator": "^13.0.0",
@ -124,13 +124,13 @@
"chai": "~4.2.0",
"cucumber": "~6.0.5",
"eslint": "~6.8.0",
"eslint-config-prettier": "~6.10.1",
"eslint-config-prettier": "~6.15.0",
"eslint-config-standard": "~14.1.1",
"eslint-plugin-import": "~2.20.2",
"eslint-plugin-jest": "~23.8.2",
"eslint-plugin-node": "~11.1.0",
"eslint-plugin-prettier": "~3.1.2",
"eslint-plugin-promise": "~4.2.1",
"eslint-plugin-promise": "~4.3.1",
"eslint-plugin-standard": "~4.0.1",
"jest": "~25.3.0",
"nodemon": "~2.0.2",

View File

@ -27,6 +27,15 @@ const request = () => {
return handler(req, res)
}
beforeAll(async () => {
await cleanDatabase()
})
afterAll(async () => {
await cleanDatabase()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -0,0 +1,8 @@
// this file is duplicated in `backend/src/config/` and `webapp/constants/` and replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/constants/
export default {
SUPPORT_EMAIL: 'devops@ocelot.social',
MODERATION_EMAIL: 'devops@ocelot.social',
// ATTENTION: the following links have to be defined even for internal pages with full URLs as example like 'https://staging.ocelot.social/support', because they are used in e-mails!
ORGANIZATION_LINK: 'https://ocelot.social',
SUPPORT_LINK: 'https://ocelot.social',
}

View File

@ -1,5 +1,5 @@
import dotenv from 'dotenv'
import links from './links.js'
import emails from './emails.js'
import metadata from './metadata.js'
// Load env file
@ -79,9 +79,9 @@ const s3 = {
const options = {
EMAIL_DEFAULT_SENDER: env.EMAIL_DEFAULT_SENDER,
SUPPORT_URL: links.SUPPORT,
SUPPORT_URL: emails.SUPPORT_LINK,
APPLICATION_NAME: metadata.APPLICATION_NAME,
ORGANIZATION_URL: links.ORGANIZATION,
ORGANIZATION_URL: emails.ORGANIZATION_LINK,
PUBLIC_REGISTRATION: env.PUBLIC_REGISTRATION === 'true' || false,
INVITE_REGISTRATION: env.INVITE_REGISTRATION !== 'false', // default = true
}

View File

@ -1,17 +0,0 @@
// this file is duplicated in `backend/src/config/links.js` and `webapp/constants/links.js` and replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/constants/
export default {
LANDING_PAGE: '/login', // examples: '/login', '/registration', '/organization', or external 'https://ocelot.social'
// you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/
SUPPORT: 'https://ocelot.social', // example for internal support page: 'https://staging.ocelot.social/support'. set a full URL please, because it is used in e-mails as well!
// on null or empty strings internal pages are used, see 'webapp/locales/html/'
ORGANIZATION: 'https://ocelot.social',
DONATE: 'https://ocelot-social.herokuapp.com/donations', // we use 'ocelot-social.herokuapp.com' at the moment, because redirections of 'ocelot.social' subpages are not working correctly
IMPRINT: 'https://ocelot-social.herokuapp.com/imprint', // we use 'ocelot-social.herokuapp.com' at the moment, because redirections of 'ocelot.social' subpages are not working correctly
TERMS_AND_CONDITIONS: null,
CODE_OF_CONDUCT: null,
DATA_PRIVACY: null,
FAQ: 'https://ocelot.social',
}

View File

@ -24,6 +24,15 @@ const neode = getNeode()
export const validAuthorizationHeader =
'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoidXNlciIsImxvY2F0aW9uTmFtZSI6bnVsbCwibmFtZSI6Ikplbm55IFJvc3RvY2siLCJhYm91dCI6bnVsbCwiYXZhdGFyIjoiaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL3VpZmFjZXMvZmFjZXMvdHdpdHRlci9zYXNoYV9zaGVzdGFrb3YvMTI4LmpwZyIsImlkIjoidTMiLCJlbWFpbCI6InVzZXJAZXhhbXBsZS5vcmciLCJzbHVnIjoiamVubnktcm9zdG9jayIsImlhdCI6MTU1MDg0NjY4MCwiZXhwIjoxNjM3MjQ2NjgwLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAiLCJzdWIiOiJ1MyJ9.eZ_mVKas4Wzoc_JrQTEWXyRn7eY64cdIg4vqQ-F_7Jc'
beforeAll(async () => {
await cleanDatabase()
})
afterAll(async () => {
await cleanDatabase()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -30,7 +30,9 @@ const updatePostMutation = gql`
}
`
beforeAll(() => {
beforeAll(async () => {
await cleanDatabase()
const createServerResult = createServer({
context: () => {
return {
@ -46,6 +48,10 @@ beforeAll(() => {
mutate = createTestClientResult.mutate
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(async () => {
hashtagingUser = await neode.create(
'User',
@ -66,6 +72,7 @@ beforeEach(async () => {
})
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -12,6 +12,8 @@ const driver = getDriver()
const neode = getNeode()
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {
@ -43,7 +45,6 @@ describe('languagesMiddleware', () => {
}
beforeAll(async () => {
await cleanDatabase()
const user = await Factory.build('user')
authenticatedUser = await user.toJson()
await Factory.build('category', {

View File

@ -37,6 +37,7 @@ const createCommentMutation = gql`
beforeAll(async () => {
await cleanDatabase()
publishSpy = jest.spyOn(pubsub, 'publish')
const createServerResult = createServer({
context: () => {
@ -53,6 +54,10 @@ beforeAll(async () => {
mutate = createTestClientResult.mutate
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(async () => {
publishSpy.mockClear()
notifiedUser = await neode.create(
@ -74,6 +79,7 @@ beforeEach(async () => {
})
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -18,6 +18,14 @@ const { server } = createServer({
})
const { query } = createTestClient(server)
beforeAll(async () => {
await cleanDatabase()
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(async () => {
await neode.create('Post', { title: 'first' })
await neode.create('Post', { title: 'second' })
@ -25,6 +33,7 @@ beforeEach(async () => {
await neode.create('Post', { title: 'last' })
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -14,6 +14,7 @@ let authenticatedUser, owner, anotherRegularUser, administrator, moderator
describe('authorization', () => {
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => ({
driver,
@ -25,6 +26,11 @@ describe('authorization', () => {
mutate = createTestClient(server).mutate
})
afterAll(async () => {
await cleanDatabase()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -13,6 +13,7 @@ const neode = getNeode()
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {
@ -25,6 +26,10 @@ beforeAll(async () => {
mutate = createTestClient(server).mutate
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(async () => {
variables = {}
const admin = await Factory.build('user', {
@ -46,6 +51,7 @@ beforeEach(async () => {
authenticatedUser = await admin.toJson()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -15,6 +15,8 @@ const action = () => {
}
beforeAll(async () => {
await cleanDatabase()
// For performance reasons we do this only once
const users = await Promise.all([
Factory.build('user', { id: 'u1', role: 'user' }),

View File

@ -19,6 +19,7 @@ const postQuery = gql`
beforeAll(async () => {
await cleanDatabase()
aUser = await Factory.build('user', {
id: 'a-user',
})

View File

@ -50,7 +50,6 @@ const reviewMutation = gql`
}
}
`
const updateUserMutation = gql`
mutation ($id: ID!, $name: String) {
UpdateUser(id: $id, name: $name) {
@ -58,7 +57,10 @@ const updateUserMutation = gql`
}
}
`
beforeAll(() => {
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {
@ -71,6 +73,10 @@ beforeAll(() => {
mutate = createTestClient(server).mutate
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(async () => {
users = await Promise.all([
Factory.build('user', {
@ -120,6 +126,7 @@ beforeEach(async () => {
offensivePost = posts[0]
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -3,6 +3,15 @@ import { getNeode } from '../db/neo4j'
const neode = getNeode()
beforeAll(async () => {
await cleanDatabase()
})
afterAll(async () => {
await cleanDatabase()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -11,6 +11,7 @@ let variables, mutate, authenticatedUser, commentAuthor, newlyCreatedComment
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {
@ -22,6 +23,10 @@ beforeAll(async () => {
mutate = createTestClient(server).mutate
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(async () => {
variables = {}
await neode.create('Category', {
@ -31,6 +36,7 @@ beforeEach(async () => {
})
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -29,6 +29,14 @@ const donationsQuery = gql`
}
`
beforeAll(async () => {
await cleanDatabase()
})
afterAll(async () => {
await cleanDatabase()
})
describe('donations', () => {
let currentUser, newlyCreatedDonations
beforeAll(async () => {
@ -52,6 +60,7 @@ describe('donations', () => {
newlyCreatedDonations = await Factory.build('donations')
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -12,12 +12,9 @@ let user
let variables
const driver = getDriver()
beforeEach(async () => {
variables = {}
})
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {
@ -31,6 +28,15 @@ beforeAll(async () => {
query = createTestClient(server).query
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(async () => {
variables = {}
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -27,7 +27,6 @@ const mutationFollowUser = gql`
}
}
`
const mutationUnfollowUser = gql`
mutation ($id: ID!) {
unfollowUser(id: $id) {
@ -40,7 +39,6 @@ const mutationUnfollowUser = gql`
}
}
`
const userQuery = gql`
query ($id: ID) {
User(id: $id) {
@ -54,6 +52,7 @@ const userQuery = gql`
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => ({
driver,
@ -70,6 +69,10 @@ beforeAll(async () => {
mutate = testClient.mutate
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(async () => {
user1 = await Factory.build(
'user',
@ -98,6 +101,7 @@ beforeEach(async () => {
variables = { id: user2.id }
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -9,12 +9,24 @@ const uuid = '[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-
let uploadCallback
let deleteCallback
beforeEach(async () => {
beforeAll(async () => {
await cleanDatabase()
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(async () => {
uploadCallback = jest.fn(({ uniqueFilename }) => `/uploads/${uniqueFilename}`)
deleteCallback = jest.fn()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})
describe('deleteImage', () => {
describe('given a resource with an image', () => {
let user

View File

@ -19,7 +19,6 @@ const generateInviteCodeMutation = gql`
}
}
`
const myInviteCodesQuery = gql`
query {
MyInviteCodes {
@ -29,7 +28,6 @@ const myInviteCodesQuery = gql`
}
}
`
const isValidInviteCodeQuery = gql`
query ($code: ID!) {
isValidInviteCode(code: $code)
@ -38,6 +36,7 @@ const isValidInviteCodeQuery = gql`
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {

View File

@ -9,7 +9,9 @@ let mutate, authenticatedUser
const driver = getDriver()
const neode = getNeode()
beforeAll(() => {
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {
@ -22,6 +24,11 @@ beforeAll(() => {
mutate = createTestClient(server).mutate
})
afterAll(async () => {
await cleanDatabase()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -54,6 +54,7 @@ const reviewMutation = gql`
describe('moderate resources', () => {
beforeAll(async () => {
await cleanDatabase()
authenticatedUser = undefined
const { server } = createServer({
context: () => {
@ -67,6 +68,10 @@ describe('moderate resources', () => {
mutate = createTestClient(server).mutate
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(async () => {
disableVariables = {
resourceId: 'undefined-resource',
@ -104,6 +109,7 @@ describe('moderate resources', () => {
)
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -12,7 +12,9 @@ let variables
let query
let mutate
beforeAll(() => {
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {
@ -25,11 +27,16 @@ beforeAll(() => {
mutate = createTestClient(server).mutate
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(async () => {
authenticatedUser = null
variables = { orderBy: 'createdAt_asc' }
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -20,11 +20,9 @@ const getAllPasswordResets = async () => {
return resets
}
beforeEach(() => {
variables = {}
})
beforeAll(async () => {
await cleanDatabase()
beforeAll(() => {
const { server } = createServer({
context: () => {
return {
@ -37,6 +35,15 @@ beforeAll(() => {
mutate = createTestClient(server).mutate
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(() => {
variables = {}
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -40,6 +40,7 @@ const createPostMutation = gql`
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {
@ -53,6 +54,10 @@ beforeAll(async () => {
mutate = createTestClient(server).mutate
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(async () => {
variables = {}
user = await Factory.build(
@ -91,6 +96,7 @@ beforeEach(async () => {
authenticatedUser = null
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -12,12 +12,9 @@ let authenticatedUser
let variables
const driver = getDriver()
beforeEach(async () => {
variables = {}
})
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {
@ -30,6 +27,15 @@ beforeAll(async () => {
mutate = createTestClient(server).mutate
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(async () => {
variables = {}
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -101,6 +101,7 @@ describe('file a report on a resource', () => {
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {
@ -114,6 +115,11 @@ describe('file a report on a resource', () => {
query = createTestClient(server).query
})
afterAll(async () => {
await cleanDatabase()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -17,6 +17,7 @@ describe('rewards', () => {
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {
@ -30,6 +31,10 @@ describe('rewards', () => {
mutate = createTestClient(server).mutate
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(async () => {
regularUser = await Factory.build(
'user',
@ -70,6 +75,7 @@ describe('rewards', () => {
})
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -11,6 +11,7 @@ const neode = getNeode()
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {

View File

@ -31,7 +31,10 @@ const queryPost = gql`
describe('shout and unshout posts', () => {
let currentUser, postAuthor
beforeAll(() => {
beforeAll(async () => {
await cleanDatabase()
authenticatedUser = undefined
const { server } = createServer({
context: () => {
@ -45,6 +48,11 @@ describe('shout and unshout posts', () => {
mutate = createTestClient(server).mutate
query = createTestClient(server).query
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(async () => {
currentUser = await Factory.build(
'user',
@ -70,6 +78,8 @@ describe('shout and unshout posts', () => {
},
)
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -6,6 +6,14 @@ import { getDriver } from '../../db/neo4j'
const driver = getDriver()
beforeAll(async () => {
await cleanDatabase()
})
afterAll(async () => {
await cleanDatabase()
})
describe('SocialMedia', () => {
let socialMediaAction, someUser, ownerNode, owner
@ -61,6 +69,7 @@ describe('SocialMedia', () => {
}
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -22,6 +22,8 @@ const statisticsQuery = gql`
}
`
beforeAll(async () => {
await cleanDatabase()
authenticatedUser = undefined
const { server } = createServer({
context: () => {
@ -33,9 +35,13 @@ beforeAll(async () => {
},
})
query = createTestClient(server).query
})
afterAll(async () => {
await cleanDatabase()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -9,8 +9,32 @@ let query, authenticatedUser
const driver = getDriver()
const neode = getNeode()
const userDataQuery = gql`
query ($id: ID!) {
userData(id: $id) {
user {
id
name
slug
}
posts {
id
title
content
comments {
content
author {
slug
}
}
}
}
}
`
beforeAll(async () => {
await cleanDatabase()
const user = await Factory.build('user', {
id: 'a-user',
name: 'John Doe',
@ -38,29 +62,6 @@ afterAll(async () => {
await cleanDatabase()
})
const userDataQuery = gql`
query ($id: ID!) {
userData(id: $id) {
user {
id
name
slug
}
posts {
id
title
content
comments {
content
author {
slug
}
}
}
}
}
`
describe('resolvers/userData', () => {
let variables = { id: 'a-user' }

View File

@ -29,12 +29,9 @@ const disable = async (id) => {
])
}
beforeEach(() => {
user = null
req = { headers: {} }
})
beforeAll(async () => {
await cleanDatabase()
beforeAll(() => {
const { server } = createServer({
context: () => {
// One of the rare occasions where we test
@ -46,6 +43,16 @@ beforeAll(() => {
mutate = createTestClient(server).mutate
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(() => {
user = null
req = { headers: {} }
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -44,7 +44,6 @@ const deleteUserMutation = gql`
}
}
`
const switchUserRoleMutation = gql`
mutation ($role: UserGroup!, $id: ID!) {
switchUserRole(role: $role, id: $id) {
@ -57,7 +56,9 @@ const switchUserRoleMutation = gql`
}
`
beforeAll(() => {
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {
@ -71,7 +72,12 @@ beforeAll(() => {
mutate = createTestClient(server).mutate
})
beforeEach(async () => {
afterAll(async () => {
await cleanDatabase()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -15,7 +15,6 @@ const updateUserMutation = gql`
}
}
`
const queryLocations = gql`
query ($place: String!, $lang: String!) {
queryLocations(place: $place, lang: $lang) {
@ -24,7 +23,6 @@ const queryLocations = gql`
}
}
`
const newlyCreatedNodesWithLocales = [
{
city: {
@ -74,7 +72,9 @@ const newlyCreatedNodesWithLocales = [
},
]
beforeAll(() => {
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {
@ -88,12 +88,19 @@ beforeAll(() => {
query = createTestClient(server).query
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(() => {
variables = {}
authenticatedUser = null
})
afterEach(cleanDatabase)
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})
describe('Location Service', () => {
// Authentication

View File

@ -12,6 +12,14 @@ let mutedUser
let authenticatedUser
let server
beforeAll(async () => {
await cleanDatabase()
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(() => {
authenticatedUser = undefined
;({ server } = createServer({
@ -28,6 +36,7 @@ beforeEach(() => {
}))
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})

View File

@ -13,6 +13,7 @@ let variables
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {

File diff suppressed because it is too large Load Diff

View File

@ -60,6 +60,11 @@ services:
networks:
- external-net
# the following network from the main YAML gives the warning `WARNING: Some networks were defined but are not used by any service: internal-net` and should be removed
# but removing is not possible yet, it seems: https://github.com/docker/compose/issues/3729#issuecomment-623154878
# networks:
# internal-net:
volumes:
webapp_node_modules:
backend_node_modules:

View File

@ -1,6 +1,6 @@
{
"name": "ocelot-social",
"version": "1.0.4",
"version": "1.0.5",
"description": "Fullstack and API tests with cypress and cucumber for ocelot.social",
"author": "ocelot.social Community",
"license": "MIT",
@ -27,13 +27,13 @@
"@babel/register": "^7.12.10",
"auto-changelog": "^2.3.0",
"bcryptjs": "^2.4.3",
"codecov": "^3.7.1",
"codecov": "^3.8.2",
"cross-env": "^7.0.3",
"cucumber": "^6.0.5",
"cypress": "^7.0.1",
"cypress-cucumber-preprocessor": "^2.2.1",
"cypress-file-upload": "^3.5.3",
"date-fns": "^2.22.1",
"date-fns": "^2.23.0",
"dotenv": "^8.2.0",
"expect": "^25.3.0",
"faker": "Marak/faker.js#master",
@ -45,7 +45,7 @@
"neode": "^0.4.7",
"npm-run-all": "^4.1.5",
"rosie": "^2.0.1",
"slug": "^2.1.1"
"slug": "^5.1.0"
},
"resolutions": {
"set-value": "^2.0.1"

View File

@ -57,8 +57,10 @@ COPY package.json yarn.lock ./
RUN yarn install --production=false --frozen-lockfile --non-interactive
COPY assets assets
# COPY components/_new/generic/ components/_new/generic
COPY components/LocaleSwitch/ components/LocaleSwitch
COPY components/Dropdown.vue components/Dropdown.vue
# COPY components/Logo/ components/Logo
COPY layouts/blank.vue layouts/blank.vue
COPY locales locales
COPY mixins mixins

View File

@ -25,10 +25,10 @@
<div v-if="formData.image" class="blur-toggle">
<label for="blur-img">{{ $t('contribution.inappropriatePicture') }}</label>
<input type="checkbox" id="blur-img" v-model="formData.imageBlurred" />
<a :href="links.FAQ" target="_blank" class="link">
{{ $t('contribution.inappropriatePictureText') }}
<page-params-link class="link" :pageParams="links.FAQ">
{{ $t('contribution.inappropriatePicture') }}
<base-icon name="question-circle" />
</a>
</page-params-link>
</div>
<ds-input
model="title"
@ -71,11 +71,13 @@ import HcEditor from '~/components/Editor/Editor'
import PostMutations from '~/graphql/PostMutations.js'
import ImageUploader from '~/components/ImageUploader/ImageUploader'
import links from '~/constants/links.js'
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
export default {
components: {
HcEditor,
ImageUploader,
PageParamsLink,
},
props: {
contribution: {

View File

@ -21,12 +21,6 @@ describe('DonationInfo.vue', () => {
const Wrapper = () => mount(DonationInfo, { mocks, localVue })
it('includes a link to the ocelot.social donations website', () => {
expect(Wrapper().find('a').attributes('href')).toBe(
'https://ocelot-social.herokuapp.com/donations',
)
})
it('displays a call to action button', () => {
expect(Wrapper().find('.base-button').text()).toBe('donations.donate-now')
})

View File

@ -1,9 +1,9 @@
<template>
<div class="donation-info">
<progress-bar :title="title" :label="label" :goal="goal" :progress="progress" />
<a target="_blank" :href="links.DONATE">
<base-button filled>{{ $t('donations.donate-now') }}</base-button>
</a>
<base-button filled @click="redirectToPage(links.DONATE)">
{{ $t('donations.donate-now') }}
</base-button>
</div>
</template>
@ -36,6 +36,11 @@ export default {
})
},
},
methods: {
redirectToPage(pageParams) {
pageParams.redirectToPage(this)
},
},
apollo: {
Donations: {
query() {

View File

@ -0,0 +1,41 @@
import { config, mount } from '@vue/test-utils'
import LoginButton from './LoginButton.vue'
config.stubs['v-popover'] = '<span><slot /></span>'
describe('LoginButton.vue', () => {
let wrapper
let mocks
let propsData
beforeEach(() => {
mocks = {
$t: jest.fn(),
navigator: {
clipboard: {
writeText: jest.fn(),
},
},
}
propsData = {}
})
describe('mount', () => {
const Wrapper = () => {
return mount(LoginButton, { mocks, propsData })
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.contains('.login-button')).toBe(true)
})
it('open popup', () => {
wrapper.find('.base-button').trigger('click')
expect(wrapper.contains('.login-button')).toBe(true)
})
})
})

View File

@ -0,0 +1,54 @@
<template>
<dropdown class="login-button" offset="8" :placement="placement">
<template #default="{ toggleMenu }">
<base-button icon="sign-in" circle ghost @click.prevent="toggleMenu" />
</template>
<template #popover>
<div class="login-button-menu-popover">
<nuxt-link class="login-link" :to="{ name: 'login' }">
<base-icon name="sign-in" />
{{ $t('login.login') }}
</nuxt-link>
</div>
</template>
</dropdown>
</template>
<script>
import Dropdown from '~/components/Dropdown'
export default {
components: {
Dropdown,
},
props: {
placement: { type: String, default: 'top-end' },
},
}
</script>
<style lang="scss" scope>
.login-button {
color: $color-secondary;
}
.login-button-menu-popover {
padding-top: $space-x-small;
padding-bottom: $space-x-small;
hr {
color: $color-neutral-90;
background-color: $color-neutral-90;
}
.login-link {
color: $text-color-base;
padding-top: $space-xx-small;
&:hover {
color: $text-color-link-active;
}
}
}
.invite-code {
left: 50%;
}
</style>

View File

@ -6,9 +6,9 @@
</blockquote>
<base-card>
<template #imageColumn>
<a :href="links.ORGANIZATION" :title="$t('login.moreInfo', metadata)" target="_blank">
<page-params-link :pageParams="links.ORGANIZATION" :title="$t('login.moreInfo', metadata)">
<logo logoType="welcome" />
</a>
</page-params-link>
</template>
<h2 class="title">{{ $t('login.login') }}</h2>
<form :disabled="pending" @submit.prevent="onSubmit">
@ -54,6 +54,7 @@
<script>
import links from '~/constants/links.js'
import metadata from '~/constants/metadata.js'
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
import Logo from '~/components/Logo/Logo'
import ShowPassword from '../ShowPassword/ShowPassword.vue'
@ -62,6 +63,7 @@ export default {
components: {
LocaleSwitch,
Logo,
PageParamsLink,
ShowPassword,
},
data() {
@ -113,7 +115,7 @@ export default {
.login-form {
width: 80vw;
max-width: 620px;
/* margin: auto; */
margin: auto;
.base-button {
display: block;

View File

@ -71,7 +71,7 @@ export default {
maintenance: {
path: logos.LOGO_MAINTENACE_RESET_PATH,
alt: 'Under Maintenance',
widthDefault: '75%',
widthDefault: '200px',
},
}
return {

View File

@ -29,8 +29,8 @@ describe('PageFooter.vue', () => {
wrapper = Wrapper()
})
it('renders four links', () => {
expect(wrapper.findAll('a')).toHaveLength(4)
it('renders five links', () => {
expect(wrapper.findAll('a')).toHaveLength(5)
})
it('renders three nuxt-links', () => {
@ -56,12 +56,12 @@ describe('PageFooter.vue', () => {
beforeEach(async () => {
const links = {
...linksDefault,
ORGANIZATION: null,
IMPRINT: null,
TERMS_AND_CONDITIONS: null,
CODE_OF_CONDUCT: null,
DATA_PRIVACY: null,
FAQ: null,
ORGANIZATION: linksDefault.ORGANIZATION.overwrite({ externalLink: null }),
IMPRINT: linksDefault.IMPRINT.overwrite({ externalLink: null }),
TERMS_AND_CONDITIONS: linksDefault.TERMS_AND_CONDITIONS.overwrite({ externalLink: null }),
CODE_OF_CONDUCT: linksDefault.CODE_OF_CONDUCT.overwrite({ externalLink: null }),
DATA_PRIVACY: linksDefault.DATA_PRIVACY.overwrite({ externalLink: null }),
FAQ: linksDefault.FAQ.overwrite({ externalLink: null }),
}
wrapper = Wrapper()
wrapper.setData({ links })
@ -77,15 +77,17 @@ describe('PageFooter.vue', () => {
})
it('renders TERMS_AND_CONDITIONS as nuxt-link', () => {
expect(wrapper.find('span[data-test="terms-nuxt-link"]').exists()).toBeTruthy()
expect(
wrapper.find('span[data-test="terms-and-conditions-nuxt-link"]').exists(),
).toBeTruthy()
})
it('renders CODE_OF_CONDUCT as nuxt-link', () => {
expect(wrapper.find('span[data-test="code-nuxt-link"]').exists()).toBeTruthy()
expect(wrapper.find('span[data-test="code-of-conduct-nuxt-link"]').exists()).toBeTruthy()
})
it('renders DATA_PRIVACY as nuxt-link', () => {
expect(wrapper.find('span[data-test="data-nuxt-link"]').exists()).toBeTruthy()
expect(wrapper.find('span[data-test="data-privacy-nuxt-link"]').exists()).toBeTruthy()
})
it('renders FAQ as nuxt-link', () => {
@ -97,12 +99,22 @@ describe('PageFooter.vue', () => {
beforeEach(async () => {
const links = {
...linksDefault,
ORGANIZATION: 'https://ocelot.social',
IMPRINT: 'https://ocelot.social/IMPRINT',
TERMS_AND_CONDITIONS: 'https://ocelot.social/TERMS_AND_CONDITIONS',
CODE_OF_CONDUCT: 'https://ocelot.social/CODE_OF_CONDUCT',
DATA_PRIVACY: 'https://ocelot.social/DATA_PRIVACY',
FAQ: 'https://ocelot.social/FAQ',
ORGANIZATION: linksDefault.ORGANIZATION.overwrite({
externalLink: 'https://ocelot.social',
}),
IMPRINT: linksDefault.IMPRINT.overwrite({
externalLink: 'https://ocelot.social/IMPRINT',
}),
TERMS_AND_CONDITIONS: linksDefault.TERMS_AND_CONDITIONS.overwrite({
externalLink: 'https://ocelot.social/TERMS_AND_CONDITIONS',
}),
CODE_OF_CONDUCT: linksDefault.CODE_OF_CONDUCT.overwrite({
externalLink: 'https://ocelot.social/CODE_OF_CONDUCT',
}),
DATA_PRIVACY: linksDefault.DATA_PRIVACY.overwrite({
externalLink: 'https://ocelot.social/DATA_PRIVACY',
}),
FAQ: linksDefault.FAQ.overwrite({ externalLink: 'https://ocelot.social/FAQ' }),
}
wrapper = Wrapper()
wrapper.setData({ links })

View File

@ -1,69 +1,12 @@
<template>
<div id="footer" class="ds-footer">
<!-- made with -->
<nuxt-link
v-if="noLinkDefined(links.ORGANIZATION)"
to="/organization"
data-test="organization-nuxt-link"
>
{{ $t('site.made') }}
</nuxt-link>
<a v-else :href="links.ORGANIZATION" target="_blank" data-test="organization-link">
{{ $t('site.made') }}
</a>
<span>-</span>
<!-- imprint -->
<nuxt-link v-if="noLinkDefined(links.IMPRINT)" to="/imprint" data-test="imprint-nuxt-link">
{{ $t('site.imprint') }}
</nuxt-link>
<a v-else :href="links.IMPRINT" target="_blank">
{{ $t('site.imprint') }}
</a>
<span>-</span>
<!-- terms and conditions -->
<nuxt-link
v-if="noLinkDefined(links.TERMS_AND_CONDITIONS)"
to="/terms-and-conditions"
data-test="terms-nuxt-link"
>
{{ $t('site.termsAndConditions') }}
</nuxt-link>
<a v-else :href="links.TERMS_AND_CONDITIONS" target="_blank">
{{ $t('site.termsAndConditions') }}
</a>
<span>-</span>
<!-- code of conduct -->
<nuxt-link
v-if="noLinkDefined(links.CODE_OF_CONDUCT)"
to="/code-of-conduct"
data-test="code-nuxt-link"
>
{{ $t('site.code-of-conduct') }}
</nuxt-link>
<a v-else :href="links.CODE_OF_CONDUCT" target="_blank">
{{ $t('site.code-of-conduct') }}
</a>
<span>-</span>
<!-- data privacy -->
<nuxt-link
v-if="noLinkDefined(links.DATA_PRIVACY)"
to="/data-privacy"
data-test="data-nuxt-link"
>
{{ $t('site.data-privacy') }}
</nuxt-link>
<a v-else :href="links.DATA_PRIVACY" target="_blank">
{{ $t('site.data-privacy') }}
</a>
<span>-</span>
<!-- faq -->
<nuxt-link v-if="noLinkDefined(links.FAQ)" to="/faq" data-test="faq-nuxt-link">
{{ $t('site.faq') }}
</nuxt-link>
<a v-else :href="links.FAQ" target="_blank">
{{ $t('site.faq') }}
</a>
<span>-</span>
<!-- links to internal or external pages -->
<span v-for="pageParams in links.FOOTER_LINK_LIST" :key="pageParams.name">
<page-params-link :pageParams="pageParams">
{{ $t(pageParams.internalPage.footerIdent) }}
</page-params-link>
<span class="division-line">-</span>
</span>
<!-- version -->
<a
href="https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/CHANGELOG.md"
@ -77,16 +20,15 @@
<script>
import links from '~/constants/links.js'
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
export default {
components: {
PageParamsLink,
},
data() {
return { links, version: `v${this.$env.VERSION}` }
},
methods: {
noLinkDefined(link) {
return !link || link.length === 0
},
},
}
</script>
@ -101,7 +43,8 @@ export default {
padding: 10px 10px;
box-shadow: 0px -6px 12px -4px rgba(0, 0, 0, 0.1);
}
span {
.division-line {
margin-left: 0.2rem;
margin-right: 0.2rem;
}
</style>

View File

@ -79,7 +79,7 @@ export default {
data() {
const passwordForm = PasswordForm({ translate: this.$t })
return {
supportEmail: emails.SUPPORT,
supportEmail: emails.SUPPORT_EMAIL,
formData: {
...passwordForm.formData,
},

View File

@ -142,7 +142,7 @@ export default {
const passwordForm = PasswordForm({ translate: this.$t })
return {
links,
supportEmail: emails.SUPPORT,
supportEmail: emails.SUPPORT_EMAIL,
formData: {
name: '',
...passwordForm.formData,

View File

@ -1,10 +1,10 @@
<template>
<section class="login-form">
<section class="registration-slider">
<base-card>
<template #imageColumn>
<a :href="links.ORGANIZATION" :title="$t('login.moreInfo', metadata)" target="_blank">
<page-params-link :pageParams="links.ORGANIZATION" :title="$t('login.moreInfo', metadata)">
<logo logoType="signup" />
</a>
</page-params-link>
</template>
<component-slider :sliderData="sliderData">
@ -48,6 +48,7 @@ import metadata from '~/constants/metadata.js'
import ComponentSlider from '~/components/ComponentSlider/ComponentSlider'
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
import Logo from '~/components/Logo/Logo'
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
import RegistrationSlideCreate from './RegistrationSlideCreate'
import RegistrationSlideEmail from './RegistrationSlideEmail'
import RegistrationSlideInvite from './RegistrationSlideInvite'
@ -60,6 +61,7 @@ export default {
ComponentSlider,
LocaleSwitch,
Logo,
PageParamsLink,
RegistrationSlideCreate,
RegistrationSlideEmail,
RegistrationSlideInvite,
@ -253,4 +255,10 @@ export default {
}
</script>
<style lang="scss"></style>
<style lang="scss">
.registration-slider {
width: 80vw;
max-width: 620px;
margin: auto;
}
</style>

View File

@ -0,0 +1,34 @@
<template>
<div>
<ds-space margin="small">
<ds-heading v-if="pageParams.internalPage.headlineIdent !== null" tag="h2">
{{ $t(pageParams.internalPage.headlineIdent) }}
</ds-heading>
</ds-space>
<ds-container v-if="pageParams.internalPage.hasContainer">
<div v-if="!pageParams.internalPage.hasBaseCard">
<br />
<div v-html="$t(pageParams.internalPage.htmlIdent)" />
</div>
<base-card v-else>
<div v-html="$t(pageParams.internalPage.htmlIdent)" />
</base-card>
</ds-container>
<div v-else-if="!pageParams.internalPage.hasBaseCard">
<br />
<div v-html="$t(pageParams.internalPage.htmlIdent)" />
</div>
<base-card v-else>
<div v-html="$t(pageParams.internalPage.htmlIdent)" />
</base-card>
</div>
</template>
<script>
export default {
name: 'InternalPage',
props: {
pageParams: { type: Object, required: true },
},
}
</script>

View File

@ -0,0 +1,21 @@
<template>
<nuxt-link
v-if="pageParams.isInternalPage"
:to="pageParams.internalPage.pageRoute"
:data-test="pageParams.name + '-nuxt-link'"
>
<slot />
</nuxt-link>
<a v-else :href="pageParams.externalLink" target="_blank" :data-test="pageParams.name + '-link'">
<slot />
</a>
</template>
<script>
export default {
name: 'PageParamsLink',
props: {
pageParams: { type: Object, required: true },
},
}
</script>

View File

@ -0,0 +1,140 @@
import { PageParams } from '~/components/utils/PageParams.js'
export const defaultPageParamsPages = {
ORGANIZATION: new PageParams({
name: 'organization',
externalLink: null, // if string is defined and not empty it's dominating
internalPage: {
pageRoute: '/organization', // static, don't change! internal page in case no external is defined
footerIdent: 'site.made', // localized string identifier
headTitleIdent: 'site.made', // localized string identifier
headlineIdent: 'site.made', // localized string identifier. on null it's hidden, on empty string default is used
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
// in case internal page content is here 'webapp/locales/html/'
htmlIdent: 'html.organization',
},
}),
DONATE: new PageParams({
name: 'donate',
externalLink: null, // if string is defined and not empty it's dominating
internalPage: {
pageRoute: '/donate', // static, don't change! internal page in case no external is defined
footerIdent: 'site.donate', // localized string identifier
headTitleIdent: 'site.donate', // localized string identifier
headlineIdent: 'site.donate', // localized string identifier. on null it's hidden, on empty string default is used
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
// in case internal page content is here 'webapp/locales/html/'
htmlIdent: 'html.donate',
},
}),
IMPRINT: new PageParams({
name: 'imprint',
externalLink: null, // if string is defined and not empty it's dominating
internalPage: {
pageRoute: '/imprint', // static, don't change! internal page in case no external is defined
footerIdent: 'site.imprint', // localized string identifier
headTitleIdent: 'site.imprint', // localized string identifier
headlineIdent: 'site.imprint', // localized string identifier. on null it's hidden, on empty string default is used
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
// in case internal page content is here 'webapp/locales/html/'
htmlIdent: 'html.imprint',
},
}),
TERMS_AND_CONDITIONS: new PageParams({
name: 'terms-and-conditions',
externalLink: null, // if string is defined and not empty it's dominating
internalPage: {
pageRoute: '/terms-and-conditions', // static, don't change! internal page in case no external is defined
footerIdent: 'site.termsAndConditions', // localized string identifier
headTitleIdent: 'site.termsAndConditions', // localized string identifier
headlineIdent: 'site.termsAndConditions', // localized string identifier. on null it's hidden, on empty string default is used
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
// in case internal page content is here 'webapp/locales/html/'
htmlIdent: 'html.termsAndConditions',
},
}),
CODE_OF_CONDUCT: new PageParams({
name: 'code-of-conduct',
externalLink: null, // if string is defined and not empty it's dominating
internalPage: {
pageRoute: '/code-of-conduct', // static, don't change! internal page in case no external is defined
footerIdent: 'site.code-of-conduct', // localized string identifier
headTitleIdent: 'site.code-of-conduct', // localized string identifier
headlineIdent: 'site.code-of-conduct', // localized string identifier. on null it's hidden, on empty string default is used
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
// in case internal page content is here 'webapp/locales/html/'
htmlIdent: 'html.codeOfConduct',
},
}),
DATA_PRIVACY: new PageParams({
name: 'data-privacy',
externalLink: null, // if string is defined and not empty it's dominating
internalPage: {
pageRoute: '/data-privacy', // static, don't change! internal page in case no external is defined
footerIdent: 'site.data-privacy', // localized string identifier
headTitleIdent: 'site.data-privacy', // localized string identifier
headlineIdent: 'site.data-privacy', // localized string identifier. on null it's hidden, on empty string default is used
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
// in case internal page content is here 'webapp/locales/html/'
htmlIdent: 'html.dataPrivacy',
},
}),
FAQ: new PageParams({
name: 'faq',
externalLink: null, // if string is defined and not empty it's dominating
internalPage: {
pageRoute: '/faq', // static, don't change! internal page in case no external is defined
footerIdent: 'site.faq', // localized string identifier
headTitleIdent: 'site.faq', // localized string identifier
headlineIdent: 'site.faq', // localized string identifier. on null it's hidden, on empty string default is used
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
// in case internal page content is here 'webapp/locales/html/'
htmlIdent: 'html.faq',
},
}),
SUPPORT: new PageParams({
name: 'support',
externalLink: null,
internalPage: {
pageRoute: '/support', // static, don't change '*/support'! internal page in case no external is defined
footerIdent: 'site.support', // localized string identifier
headTitleIdent: 'site.support', // localized string identifier
headlineIdent: 'site.support', // localized string identifier. on null it's hidden, on empty string default is used
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
// in case internal page content is here 'webapp/locales/html/'
htmlIdent: 'html.support',
},
}),
}

View File

@ -0,0 +1,41 @@
export class PageParams {
constructor(pageParams) {
this.name = pageParams.name
this.externalLink = pageParams.externalLink
this.internalPage = pageParams.internalPage
}
overwrite(assignPageParams) {
const pageParams = this
if (assignPageParams.name !== undefined) {
pageParams.name = assignPageParams.name
}
if (assignPageParams.externalLink !== undefined) {
pageParams.externalLink = assignPageParams.externalLink
}
if (assignPageParams.internalPage !== undefined) {
pageParams.internalPage = { ...pageParams.internalPage, ...assignPageParams.internalPage }
}
return pageParams
}
noStringDefined(string) {
return !string || string.length === 0
}
get isInternalPage() {
return this.noStringDefined(this.externalLink)
}
get link() {
return this.isInternalPage ? this.internalPage.pageRoute : this.externalLink
}
redirectToPage(thisComponent) {
if (this.isInternalPage) {
thisComponent.$router.push(this.internalPage.pageRoute)
} else if (typeof window !== 'undefined') {
window.location.href = this.externalLink
}
}
}

View File

@ -1,4 +1,8 @@
// this file is duplicated in `backend/src/config/` and `webapp/constants/` and replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/constants/
export default {
SUPPORT: 'devops@ocelot.social',
MODERATION: 'devops@ocelot.social',
SUPPORT_EMAIL: 'devops@ocelot.social',
MODERATION_EMAIL: 'devops@ocelot.social',
// ATTENTION: the following links have to be defined even for internal pages with full URLs as example like 'https://staging.ocelot.social/support', because they are used in e-mails!
ORGANIZATION_LINK: 'https://ocelot.social',
SUPPORT_LINK: 'https://ocelot.social',
}

View File

@ -1,17 +1,136 @@
// this file is duplicated in `backend/src/config/links.js` and `webapp/constants/links.js` and replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/constants/
// this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/constants/
import { defaultPageParamsPages } from '~/components/utils/InternalPages.js'
const ORGANIZATION = defaultPageParamsPages.ORGANIZATION.overwrite({
externalLink: 'https://ocelot.social', // if string is defined and not empty it's dominating
internalPage: {
// footerIdent: 'site.made', // localized string identifier, if undefined default is used
// headTitleIdent: 'site.made', // localized string identifier, if undefined default is used
// headlineIdent: 'site.made', // localized string identifier, on null it's hidden, if undefined default is used
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
// in case internal page content is here 'webapp/locales/html/'
},
})
const DONATE = defaultPageParamsPages.DONATE.overwrite({
// we use 'ocelot-social.herokuapp.com' at the moment, because redirections of 'ocelot.social' subpages are not working correctly
externalLink: 'https://ocelot-social.herokuapp.com/donations', // if string is defined and not empty it's dominating
internalPage: {
// footerIdent: 'site.donate', // localized string identifier, if undefined default is used
// headTitleIdent: 'site.donate', // localized string identifier, if undefined default is used
// headlineIdent: 'site.donate', // localized string identifier, on null it's hidden, if undefined default is used
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
// in case internal page content is here 'webapp/locales/html/'
},
})
const IMPRINT = defaultPageParamsPages.IMPRINT.overwrite({
// we use 'ocelot-social.herokuapp.com' at the moment, because redirections of 'ocelot.social' subpages are not working correctly
externalLink: 'https://ocelot-social.herokuapp.com/imprint', // if string is defined and not empty it's dominating
internalPage: {
// footerIdent: 'site.imprint', // localized string identifier, if undefined default is used
// headTitleIdent: 'site.imprint', // localized string identifier, if undefined default is used
// headlineIdent: 'site.imprint', // localized string identifier, on null it's hidden, if undefined default is used
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
// in case internal page content is here 'webapp/locales/html/'
},
})
const TERMS_AND_CONDITIONS = defaultPageParamsPages.TERMS_AND_CONDITIONS.overwrite({
// externalLink: null, // if string is defined and not empty it's dominating
internalPage: {
// footerIdent: 'site.termsAndConditions', // localized string identifier, if undefined default is used
// headTitleIdent: 'site.termsAndConditions', // localized string identifier, if undefined default is used
// headlineIdent: 'site.termsAndConditions', // localized string identifier, on null it's hidden, if undefined default is used
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
// in case internal page content is here 'webapp/locales/html/'
},
})
const CODE_OF_CONDUCT = defaultPageParamsPages.CODE_OF_CONDUCT.overwrite({
// externalLink: null, // if string is defined and not empty it's dominating
internalPage: {
// footerIdent: 'site.code-of-conduct', // localized string identifier, if undefined default is used
// headTitleIdent: 'site.code-of-conduct', // localized string identifier, if undefined default is used
// headlineIdent: 'site.code-of-conduct', // localized string identifier, on null it's hidden, if undefined default is used
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
// in case internal page content is here 'webapp/locales/html/'
},
})
const DATA_PRIVACY = defaultPageParamsPages.DATA_PRIVACY.overwrite({
// externalLink: null, // if string is defined and not empty it's dominating
internalPage: {
// footerIdent: 'site.data-privacy', // localized string identifier, if undefined default is used
// headTitleIdent: 'site.data-privacy', // localized string identifier, if undefined default is used
// headlineIdent: 'site.data-privacy', // localized string identifier, on null it's hidden, if undefined default is used
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
// in case internal page content is here 'webapp/locales/html/'
},
})
const FAQ = defaultPageParamsPages.FAQ.overwrite({
externalLink: 'https://ocelot.social', // if string is defined and not empty it's dominating
internalPage: {
// footerIdent: 'site.faq', // localized string identifier, if undefined default is used
// headTitleIdent: 'site.faq', // localized string identifier, if undefined default is used
// headlineIdent: 'site.faq', // on null default is used, on empty string it's hidden
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
// in case internal page content is here 'webapp/locales/html/'
},
})
const SUPPORT = defaultPageParamsPages.SUPPORT.overwrite({
externalLink: 'https://ocelot.social', // if string is defined and not empty it's dominating
internalPage: {
// footerIdent: 'site.support', // localized string identifier, if undefined default is used
// headTitleIdent: 'site.support', // localized string identifier, if undefined default is used
// headlineIdent: 'site.support', // on null default is used, on empty string it's hidden
hasContainer: true,
hasBaseCard: true,
hasLoginInHeader: true,
// in case internal page content is here 'webapp/locales/html/'
},
})
export default {
LANDING_PAGE: '/login', // examples: '/login', '/registration', '/organization', or external 'https://ocelot.social'
// you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/
// you can find and store templates for 👇🏼 at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/
SUPPORT: 'https://ocelot.social', // example for internal support page: 'https://staging.ocelot.social/support'. set a full URL please, because it is used in e-mails as well!
ORGANIZATION,
DONATE,
IMPRINT,
TERMS_AND_CONDITIONS,
CODE_OF_CONDUCT,
DATA_PRIVACY,
FAQ,
SUPPORT,
// on null or empty strings internal pages are used, see 'webapp/locales/html/'
ORGANIZATION: 'https://ocelot.social',
DONATE: 'https://ocelot-social.herokuapp.com/donations', // we use 'ocelot-social.herokuapp.com' at the moment, because redirections of 'ocelot.social' subpages are not working correctly
IMPRINT: 'https://ocelot-social.herokuapp.com/imprint', // we use 'ocelot-social.herokuapp.com' at the moment, because redirections of 'ocelot.social' subpages are not working correctly
TERMS_AND_CONDITIONS: null,
CODE_OF_CONDUCT: null,
DATA_PRIVACY: null,
FAQ: 'https://ocelot.social',
FOOTER_LINK_LIST: [
ORGANIZATION,
TERMS_AND_CONDITIONS,
CODE_OF_CONDUCT,
DATA_PRIVACY,
FAQ,
DONATE,
IMPRINT,
// SUPPORT,
],
}

View File

@ -1,3 +1,4 @@
import Vuex from 'vuex'
import { config, shallowMount } from '@vue/test-utils'
import Basic from './basic.vue'
@ -8,16 +9,23 @@ config.stubs.nuxt = '<span><slot /></span>'
describe('basic.vue', () => {
let wrapper
let mocks
let store
beforeEach(() => {
mocks = {
$t: jest.fn(),
}
store = new Vuex.Store({
getters: {
'auth/isLoggedIn': () => true,
},
})
})
describe('shallow mount', () => {
const Wrapper = () => {
return shallowMount(Basic, {
store,
mocks,
localVue,
})

View File

@ -10,7 +10,14 @@
</a>
</ds-flex-item>
<ds-flex-item width="20%" style="flex-grow: 0">
<locale-switch class="topbar-locale-switch" placement="top" offset="16" />
<div class="main-navigation-right" style="flex-basis: auto">
<locale-switch class="topbar-locale-switch" placement="top" offset="8" />
<template v-if="!isLoggedIn">
<client-only>
<login-button placement="top" />
</client-only>
</template>
</div>
</ds-flex-item>
</ds-flex>
</ds-container>
@ -26,18 +33,26 @@
</template>
<script>
import { mapGetters } from 'vuex'
import seo from '~/mixins/seo'
import Logo from '~/components/Logo/Logo'
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
import seo from '~/mixins/seo'
import LoginButton from '~/components/LoginButton/LoginButton'
import PageFooter from '~/components/PageFooter/PageFooter'
export default {
components: {
Logo,
LocaleSwitch,
LoginButton,
PageFooter,
},
mixins: [seo],
computed: {
...mapGetters({
isLoggedIn: 'auth/isLoggedIn',
}),
},
methods: {
redirectToRoot() {
this.$router.replace('/')
@ -45,3 +60,13 @@ export default {
},
}
</script>
<style lang="scss">
.main-navigation-right {
display: flex;
justify-content: flex-end;
}
.main-navigation-right .desktop-view {
float: right;
}
</style>

View File

@ -781,6 +781,7 @@
"contact": "Kontakt",
"data-privacy": "Datenschutzerklärung",
"director": "Geschäftsführer",
"donate": "Spenden",
"error-occurred": "Ein Fehler ist aufgetreten.",
"faq": "FAQ",
"germany": "Deutschland",

View File

@ -781,6 +781,7 @@
"contact": "Contact",
"data-privacy": "Data privacy",
"director": "Managing Director",
"donate": "Donate",
"error-occurred": "An error occurred.",
"faq": "FAQ",
"germany": "Germany",

View File

@ -1,5 +1,4 @@
<!-- this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/locales/html/ -->
<!-- you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/ -->
<br>
<p>Ich bin der Inhalt vom Verhaltenskodex.</p>

View File

@ -1,5 +1,4 @@
<!-- this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/locales/html/ -->
<!-- you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/ -->
<br>
<p>Das hier wäre der Inhalt der Datenschutzbestimmungen.</p>

View File

@ -0,0 +1,4 @@
<!-- this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/locales/html/ -->
<!-- you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/ -->
<p>Hier steht was zu den Spenden.</p>

View File

@ -1,5 +1,4 @@
<!-- this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/locales/html/ -->
<!-- you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/ -->
<br>
<p>Hier stehen die FAQs.</p>

View File

@ -1,5 +1,4 @@
<!-- this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/locales/html/ -->
<!-- you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/ -->
<br>
<p>Ich bin das Impressum.</p>

View File

@ -5,6 +5,7 @@ import codeOfConduct from './code-of-conduct.html'
import dataPrivacy from './data-privacy.html'
import faq from './faq.html'
import imprint from './imprint.html'
import donate from './donate.html'
export default {
organization,
@ -14,4 +15,5 @@ export default {
dataPrivacy,
faq,
imprint,
donate,
}

View File

@ -1,5 +1,4 @@
<!-- this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/locales/html/ -->
<!-- you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/ -->
<br>
<p>Hier wird das Netzwerk beschrieben.</p>

View File

@ -1,5 +1,4 @@
<!-- this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/locales/html/ -->
<!-- you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/ -->
<br>
<p>Ich bin der Inhalt vom Support.</p>

View File

@ -1,5 +1,4 @@
<!-- this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/locales/html/ -->
<!-- you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/ -->
<br>
<p>Ich bin der Inhalt der Seite "Nutzungsbedingungen".</p>

View File

@ -1,5 +1,4 @@
<!-- this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/locales/html/ -->
<!-- you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/ -->
<br>
<p>I am the content of the code of conduct.</p>

View File

@ -1,5 +1,4 @@
<!-- this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/locales/html/ -->
<!-- you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/ -->
<br>
<p>This would be our data privacy section.</p>

View File

@ -0,0 +1,4 @@
<!-- this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/locales/html/ -->
<!-- you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/ -->
<p>Here's what it says about donations.</p>

View File

@ -1,5 +1,4 @@
<!-- this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/locales/html/ -->
<!-- you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/ -->
<br>
<p>Here are the FAQs.</p>

View File

@ -1,5 +1,4 @@
<!-- this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/locales/html/ -->
<!-- you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/ -->
<br>
<p>I am the imprint.</p>

View File

@ -5,6 +5,7 @@ import codeOfConduct from './code-of-conduct.html'
import dataPrivacy from './data-privacy.html'
import faq from './faq.html'
import imprint from './imprint.html'
import donate from './donate.html'
export default {
organization,
@ -14,4 +15,5 @@ export default {
dataPrivacy,
faq,
imprint,
donate,
}

View File

@ -1,5 +1,4 @@
<!-- this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/locales/html/ -->
<!-- you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/ -->
<br>
<p>Here the network is described.</p>

View File

@ -1,5 +1,4 @@
<!-- this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/locales/html/ -->
<!-- you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/ -->
<br>
<p>I am the content of the support.</p>

View File

@ -1,5 +1,4 @@
<!-- this file is replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/locales/html/ -->
<!-- you can find and store templates at https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/templates/ -->
<br>
<p>I am the content of the page "Terms And Conditions".<p>

View File

@ -1,6 +1,6 @@
{
"name": "@ocelot-social/maintenance",
"version": "1.0.3",
"version": "1.0.5",
"description": "Maintenance page for ocelot.social",
"repository": "https://github.com/Ocelot-Social-Community/Ocelot-Social",
"author": "ocelot.social Community",

View File

@ -8,9 +8,19 @@
<ds-flex>
<ds-flex-item :width="{ base: '100%', sm: 1, md: 1 }">
<ds-space>
<a :href="links.ORGANIZATION" :title="$t('login.moreInfo', metadata)" target="_blank">
<img class="image" alt="Under maintenance" src="/img/custom/logo-squared.svg" />
</a>
<!-- QUESTION: could we have internal page or even all internal pages here as well with PageParamsLink by having the footer underneath? -->
<!-- I tried this out, but only could get the nginx page displayed. I guees the there were nuxt errors, because the nuxt config file 'webapp/maintenance/source/nuxt.config.maintenance.js' would have to be refactored for that as well and may be the missing folder `components/_new/generic/` plays a role, see https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4619 -->
<!-- <page-params-link :pageParams="links.ORGANIZATION" :title="$t('login.moreInfo', metadata)">
<logo type="maintenance" />
</page-params-link> -->
<!-- BUT: not the logo and not even the a-tag is working at the moment -->
<!-- <a
:href="emails.ORGANIZATION_LINK"
:title="$t('login.moreInfo', metadata)"
target="_blank"
> -->
<img class="image" alt="Under maintenance" src="/img/custom/logo-squared.svg" />
<!-- </a> -->
</ds-space>
</ds-flex-item>
<ds-flex-item :width="{ base: '100%', sm: 1, md: 1 }">
@ -35,17 +45,20 @@
<script>
import emails from '~/constants/emails.js'
import links from '~/constants/links.js'
// import links from '~/constants/links.js'
import metadata from '~/constants/metadata.js'
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
// import Logo from '~/components/Logo/Logo'
export default {
layout: 'blank',
components: {
LocaleSwitch,
// Logo,
},
data() {
return { links, metadata, supportEmail: emails.SUPPORT }
// return { links, metadata, supportEmail: emails.SUPPORT_EMAIL }
return { metadata, supportEmail: emails.SUPPORT_EMAIL }
},
}
</script>

View File

@ -0,0 +1,26 @@
import InternalPage from '~/components/_new/features/InternalPage/InternalPage.vue'
export function internalPageMixins(pageParams) {
return {
layout: 'basic',
components: {
InternalPage,
},
data() {
return { pageParams }
},
head() {
return {
title: this.$t(this.pageParams.internalPage.headTitleIdent),
}
},
created() {
if (!this.pageParams.isInternalPage) {
// to avoid possible errors, because 'window' is only defined on browser side but not in NodeJS on client side. check for 'typeof window' is neccessary, because if it's not defined at all you can't check for 'window !== undefined' without the same error 'window is undefined'
if (typeof window !== 'undefined') {
window.location.href = this.pageParams.externalLink
}
}
},
}
}

View File

@ -45,6 +45,7 @@ export default {
'imprint',
'data-privacy',
'faq',
'donate',
],
// pages to keep alive
keepAlivePages: ['index'],

36997
webapp/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "ocelot-social-webapp",
"version": "1.0.4",
"version": "1.0.5",
"description": "ocelot.social Frontend",
"repository": "https://github.com/Ocelot-Social-Community/Ocelot-Social",
"author": "ocelot.social Community",
@ -98,7 +98,7 @@
"vue-infinite-loading": "^2.4.5",
"vue-izitoast": "^1.2.1",
"vue-observe-visibility": "^1.0.0",
"vue-scrollto": "^2.17.1",
"vue-scrollto": "^2.20.0",
"vue-sweetalert-icons": "~4.3.0",
"vuex-i18n": "~1.13.1",
"xregexp": "^4.3.0",
@ -108,7 +108,7 @@
"@babel/core": "~7.12.3",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/preset-env": "~7.9.0",
"@storybook/addon-a11y": "^5.3.18",
"@storybook/addon-a11y": "^6.3.6",
"@storybook/addon-actions": "^5.3.21",
"@storybook/addon-notes": "^5.3.18",
"@storybook/vue": "~6.3.6",
@ -132,7 +132,7 @@
"eslint-plugin-import": "~2.20.2",
"eslint-plugin-jest": "~24.4.0",
"eslint-plugin-node": "~11.1.0",
"eslint-plugin-prettier": "~3.1.4",
"eslint-plugin-prettier": "~3.4.0",
"eslint-plugin-promise": "~4.3.1",
"eslint-plugin-standard": "~5.0.0",
"eslint-plugin-vue": "~6.2.2",

View File

@ -5,6 +5,11 @@ import VueMeta from 'vue-meta'
const localVue = global.localVue
localVue.use(VueMeta, { keyName: 'head' })
// avoid: 'Error: Not implemented: navigation (except hash changes)', see https://stackoverflow.com/questions/54090231/how-to-fix-error-not-implemented-navigation-except-hash-changes
const assignMock = jest.fn()
delete window.location
window.location = { assign: assignMock }
describe('code-of-conduct.vue', () => {
let wrapper
let mocks
@ -28,7 +33,7 @@ describe('code-of-conduct.vue', () => {
})
it('renders', () => {
expect(wrapper.is('div')).toBe(true)
expect(wrapper.is('div')).toBeTruthy()
})
it('has correct <head> content', () => {

View File

@ -1,21 +1,12 @@
<template>
<div>
<ds-space margin="small">
<ds-heading tag="h2">{{ $t('site.code-of-conduct') }}</ds-heading>
</ds-space>
<ds-container>
<div v-html="$t('html.codeOfConduct')" />
</ds-container>
</div>
<internal-page :pageParams="pageParams" />
</template>
<script>
import links from '~/constants/links.js'
import { internalPageMixins } from '~/mixins/internalPageMixins'
export default {
layout: 'basic',
head() {
return {
title: this.$t('site.code-of-conduct'),
}
},
mixins: [internalPageMixins(links.CODE_OF_CONDUCT)],
}
</script>

View File

@ -5,6 +5,11 @@ import VueMeta from 'vue-meta'
const localVue = global.localVue
localVue.use(VueMeta, { keyName: 'head' })
// avoid: 'Error: Not implemented: navigation (except hash changes)', see https://stackoverflow.com/questions/54090231/how-to-fix-error-not-implemented-navigation-except-hash-changes
const assignMock = jest.fn()
delete window.location
window.location = { assign: assignMock }
describe('data-privacy.vue', () => {
let wrapper
let mocks
@ -28,7 +33,7 @@ describe('data-privacy.vue', () => {
})
it('renders', () => {
expect(wrapper.is('div')).toBe(true)
expect(wrapper.is('div')).toBeTruthy()
})
it('has correct <head> content', () => {

View File

@ -1,21 +1,12 @@
<template>
<div>
<ds-space margin="small">
<ds-heading tag="h2">{{ $t('site.data-privacy') }}</ds-heading>
</ds-space>
<ds-container>
<div v-html="$t('html.dataPrivacy')" />
</ds-container>
</div>
<internal-page :pageParams="pageParams" />
</template>
<script>
import links from '~/constants/links.js'
import { internalPageMixins } from '~/mixins/internalPageMixins'
export default {
layout: 'basic',
head() {
return {
title: this.$t('site.data-privacy'),
}
},
mixins: [internalPageMixins(links.DATA_PRIVACY)],
}
</script>

View File

@ -0,0 +1,43 @@
import { mount } from '@vue/test-utils'
import Donate from './donate.vue'
import VueMeta from 'vue-meta'
const localVue = global.localVue
localVue.use(VueMeta, { keyName: 'head' })
// avoid: 'Error: Not implemented: navigation (except hash changes)', see https://stackoverflow.com/questions/54090231/how-to-fix-error-not-implemented-navigation-except-hash-changes
const assignMock = jest.fn()
delete window.location
window.location = { assign: assignMock }
describe('donate.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: (t) => t,
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(Donate, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.is('div')).toBeTruthy()
})
it('has correct <head> content', () => {
expect(wrapper.vm.$metaInfo.title).toBe('site.donate')
})
})
})

12
webapp/pages/donate.vue Normal file
View File

@ -0,0 +1,12 @@
<template>
<internal-page :pageParams="pageParams" />
</template>
<script>
import links from '~/constants/links.js'
import { internalPageMixins } from '~/mixins/internalPageMixins'
export default {
mixins: [internalPageMixins(links.DONATE)],
}
</script>

View File

@ -5,6 +5,11 @@ import VueMeta from 'vue-meta'
const localVue = global.localVue
localVue.use(VueMeta, { keyName: 'head' })
// avoid: 'Error: Not implemented: navigation (except hash changes)', see https://stackoverflow.com/questions/54090231/how-to-fix-error-not-implemented-navigation-except-hash-changes
const assignMock = jest.fn()
delete window.location
window.location = { assign: assignMock }
describe('faq.vue', () => {
let wrapper
let mocks
@ -28,7 +33,7 @@ describe('faq.vue', () => {
})
it('renders', () => {
expect(wrapper.is('div')).toBe(true)
expect(wrapper.is('div')).toBeTruthy()
})
it('has correct <head> content', () => {

Some files were not shown because too many files have changed in this diff Show More