Merge branch 'master' of github.com:Ocelot-Social-Community/Ocelot-Social into dependabot/npm_and_yarn/cross-env-7.0.3

This commit is contained in:
Wolfgang Huß 2021-07-21 14:57:25 +02:00
commit a58c72e6d3
174 changed files with 7402 additions and 1954 deletions

View File

@ -1,25 +1,9 @@
--- ---
name: 🐛 Bug report name: 🐛 Bug Report
about: Create a report to help us improve about: Create a report to help us to improve.
labels: bug labels: bug
title: 🐛 [Bug] title: 🐛 [Bug]
--- ---
## :bug: Bugreport ## :bug: Bug Report
<!-- Describe your issue in detail. Include screenshots if needed. Give us as much information as possible. Use a clear and concise description of what the bug is.--> <!-- Describe your issue in detail. Include screenshots if needed. Give us as much information as possible. Use a clear and concise description of what the bug is.-->
### Steps to reproduce the behavior
1.
2.
3.
4. ...
5. Profit
### Expected behavior
<!-- A clear and concise description of what you expected to happen. -->
### Version & Environment
<!-- Add context about your environment and used version here. -->
### Additional context
<!-- Add any other context about the problem here. -->

View File

@ -1,24 +1,9 @@
--- ---
name: 💥 DevOps ticket name: 💥 DevOps Ticket
about: Help us manage our deployed App. about: Help us manage our deployed app.
labels: devops labels: devops
title: 💥 [DevOps] title: 💥 [DevOps]
--- ---
## 💥 DevOps ticket ## 💥 DevOps Ticket
<!-- Describe your issue in detail. Include screenshots if needed. Give us as much information as possible. Use a clear and concise description of what the problem is.--> <!-- Describe your issue in detail. Include screenshots if needed. Give us as much information as possible. Use a clear and concise description of what the problem is.-->
### Motive
<!-- Why does this task need to be done? What can we benefit from this? -->
### Related issues
<!-- Are there any related issues to link to? Please paste them below for reference. -->
### Implementation
<!-- Please, document any ideas of how the task can be performed. -->
### Validation
<!-- How can we make sure that this task was successful? -->
### Additional context
<!-- Add other context or background about the feature request here.-->

12
.github/ISSUE_TEMPLATE/epic.md vendored Normal file
View File

@ -0,0 +1,12 @@
---
name: 🌟 Epic
about: Define a big development step.
labels: epic
title: 🌟 [EPIC]
---
<!-- THIS ISSUE-TYPE IS NOT FOR YOU! -->
<!-- If you need an answer right away, visit the ocelot.social Discord:
https://discord.gg/AJSX9DCSUA -->
## 🌟 EPIC
<!-- Describe your Epic in detail. Include screenshots and drawings -->

View File

@ -1,24 +1,9 @@
--- ---
name: 🚀 Feature request name: 🚀 Feature Request
about: Suggest an idea for this project about: Suggest an idea for this project.
labels: feature labels: feature
title: 🚀 [Feature] title: 🚀 [Feature]
--- ---
## :rocket: Feature ## :rocket: Feature Request
<!-- Give a short summary of the Feature. Use Screenshots if you want. --> <!-- Give a short summary of the Feature. Use Screenshots if you want. -->
### User Problem
<!-- Which problem is this solving? Why do you think this is important? Who will benefit from it and how? -->
### Implementation
<!-- How do you think this feature should be implemented? How will it be used? Where in the network should it be located? Which steps and screens are involved? -->
### Design & Layout
<!-- Attach Screenshots and Sketches to illustrate your idea. -->
### Validation
<!-- How can we make sure that this feature indeed solves the above problem? How do we know if it has been accepted by the users of the network, once released? -->
### Additional context
<!-- Add other context or background about the feature request here.-->

View File

@ -1,12 +1,12 @@
--- ---
name: 💬 Question name: 💬 Question
about: If you need help understanding HumanConnection. about: If you need help understanding ocelot.social.
labels: question labels: question
title: 💬 [Question] title: 💬 [Question]
--- ---
<!-- Chat with Team HumanConnection --> <!-- Chat with ocelot.social team -->
<!-- If you need an answer right away, visit the HumanConnection Discord: <!-- If you need an answer right away, visit the ocelot.social Discord:
https://discord.gg/Q3mpcgr --> https://discord.gg/AJSX9DCSUA -->
## :speech_balloon: Question ## 💬 Question
<!-- Describe your Question in detail. Include screenshots and drawings if needed. --> <!-- Describe your Question in detail. Include screenshots and drawings if needed. -->

View File

@ -1,21 +1,10 @@
--- ---
name: 🔧 Refactor ticket name: 🔧 Refactor
about: Help us improve our code by refactoring it. about: Help us improve our code by refactoring it.
labels: refactor labels: refactor
title: 🔧 [Refactor] title: 🔧 [Refactor]
--- ---
## :zap: Refactor ticket ## 🔧 Refactor
<!-- Describe your issue in detail. Include screenshots if needed. Give us as much information as possible. Use a clear and concise description of what the problem is.--> <!-- Describe your issue in detail. Include screenshots if needed. Give us as much information as possible. Use a clear and concise description of what the problem is.-->
### Motive
<!-- What is the purpose of this refactoring? If it's removing depcrecated code, please link to the deprecation notice. -->
### Related issues
<!-- Are there any related issues to link to? Please paste them below for reference. -->
### Implementation
<!-- Please, document any ideas of how the code should be refactored. -->
### Additional context
<!-- Add other context or background about the feature request here.-->

179
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,179 @@
version: 2
updates:
- package-ecosystem: npm
directory: "/"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
ignore:
- dependency-name: cypress
versions:
- 6.3.0
- 6.4.0
- 6.5.0
- 6.6.0
- 6.7.1
- 6.8.0
- 7.0.0
- 7.0.1
- 7.1.0
- dependency-name: cypress-cucumber-preprocessor
versions:
- 4.0.0
- 4.0.1
- 4.0.3
- dependency-name: date-fns
versions:
- 2.16.1
- 2.17.0
- 2.18.0
- 2.19.0
- 2.20.0
- 2.20.1
- 2.20.2
- 2.20.3
- 2.21.0
- dependency-name: cypress-file-upload
versions:
- 5.0.2
- 5.0.3
- 5.0.4
- 5.0.5
- dependency-name: neo4j-driver
versions:
- 4.2.2
- package-ecosystem: npm
directory: "/backend"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
ignore:
- dependency-name: y18n
versions:
- 4.0.1
- 4.0.2
- dependency-name: metascraper-publisher
versions:
- 5.16.16
- 5.18.1
- 5.18.12
- 5.18.2
- 5.18.4
- 5.18.5
- 5.18.6
- 5.18.9
- 5.20.0
- 5.21.0
- 5.21.2
- 5.21.3
- 5.21.4
- 5.21.5
- dependency-name: metascraper-author
versions:
- 5.16.16
- 5.18.1
- 5.18.12
- 5.18.2
- 5.18.4
- 5.18.5
- 5.18.6
- 5.18.9
- 5.20.0
- 5.21.0
- 5.21.2
- 5.21.3
- 5.21.4
- 5.21.5
- dependency-name: neo4j-driver
versions:
- 4.2.2
- dependency-name: neo4j-graphql-js
versions:
- 2.19.1
- dependency-name: mustache
versions:
- 4.1.0
- package-ecosystem: npm
directory: "/webapp"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
ignore:
- dependency-name: nuxt
versions:
- 2.14.12
- 2.15.0
- 2.15.1
- 2.15.2
- 2.15.3
- dependency-name: v-tooltip
versions:
- 2.1.2
- dependency-name: "@vue/server-test-utils"
versions:
- 1.1.2
- 1.1.3
- dependency-name: node-notifier
versions:
- 8.0.1
- package-ecosystem: docker
directory: "/webapp"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
ignore:
- dependency-name: node
versions:
- ">= 15.5.a, < 15.6"
- dependency-name: node
versions:
- 15.10.0.pre.alpine3.10
- 15.11.0.pre.alpine3.10
- 15.12.0.pre.alpine3.10
- 15.13.0.pre.alpine3.10
- 15.7.0.pre.alpine3.10
- 15.8.0.pre.alpine3.10
- 15.9.0.pre.alpine3.10
- package-ecosystem: docker
directory: "/backend"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
ignore:
- dependency-name: node
versions:
- ">= 15.4.a, < 15.5"
- dependency-name: node
versions:
- ">= 15.5.a, < 15.6"
- dependency-name: node
versions:
- 15.10.0.pre.alpine3.10
- 15.11.0.pre.alpine3.10
- 15.12.0.pre.alpine3.10
- 15.13.0.pre.alpine3.10
- 15.7.0.pre.alpine3.10
- 15.8.0.pre.alpine3.10
- 15.9.0.pre.alpine3.10
- package-ecosystem: docker
directory: "/neo4j"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
ignore:
- dependency-name: neo4j
versions:
- 4.2.3
- 4.2.4
- package-ecosystem: docker
directory: "/deployment/legacy-migration/maintenance-worker"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10

View File

@ -4,6 +4,7 @@ on:
push: push:
branches: branches:
- master - master
# - 4451-new-deployment-with-base-and-code # for testing while developing
jobs: jobs:
############################################################################## ##############################################################################
@ -55,9 +56,9 @@ jobs:
# NEO4J ################################################################## # NEO4J ##################################################################
########################################################################## ##########################################################################
- name: Neo4J | Build `community` image - name: Neo4J | Build `community` image
run: | run: docker build --target community -t "ocelotsocialnetwork/neo4j:latest" -t "ocelotsocialnetwork/neo4j:community" -t "ocelotsocialnetwork/neo4j:${VERSION}" -t "ocelotsocialnetwork/neo4j:${BUILD_VERSION}" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT neo4j/
docker build --target community -t "ocelotsocialnetwork/neo4j:latest" -t "ocelotsocialnetwork/neo4j:community" -t "ocelotsocialnetwork/neo4j:${VERSION}" -t "ocelotsocialnetwork/neo4j:${BUILD_VERSION}" neo4j/ - name: Neo4J | Save docker image
docker save "ocelotsocialnetwork/neo4j" > /tmp/neo4j.tar run: docker save "ocelotsocialnetwork/neo4j" > /tmp/neo4j.tar
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
@ -91,10 +92,13 @@ jobs:
########################################################################## ##########################################################################
# BUILD BACKEND DOCKER IMAGE (production) ################################ # BUILD BACKEND DOCKER IMAGE (production) ################################
########################################################################## ##########################################################################
- name: backend | Build `production` image - name: Backend | Build `production` image
run: | run: |
docker build --target production -t "ocelotsocialnetwork/backend:latest" -t "ocelotsocialnetwork/backend:${VERSION}" -t "ocelotsocialnetwork/backend:${BUILD_VERSION}" backend/ docker build --target base -t "ocelotsocialnetwork/backend:latest-base" -t "ocelotsocialnetwork/backend:${VERSION}-base" -t "ocelotsocialnetwork/backend:${BUILD_VERSION}-base" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT backend/
docker save "ocelotsocialnetwork/backend" > /tmp/backend.tar docker build --target code -t "ocelotsocialnetwork/backend:latest-code" -t "ocelotsocialnetwork/backend:${VERSION}-code" -t "ocelotsocialnetwork/backend:${BUILD_VERSION}-code" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT backend/
docker build --target production -t "ocelotsocialnetwork/backend:latest" -t "ocelotsocialnetwork/backend:${VERSION}" -t "ocelotsocialnetwork/backend:${BUILD_VERSION}" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT backend/
- name: Backend | Save docker image
run: docker save "ocelotsocialnetwork/backend" > /tmp/backend.tar
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
@ -128,10 +132,13 @@ jobs:
########################################################################## ##########################################################################
# BUILD WEBAPP DOCKER IMAGE (build) ###################################### # BUILD WEBAPP DOCKER IMAGE (build) ######################################
########################################################################## ##########################################################################
- name: webapp | Build `production` image - name: Webapp | Build `production` image
run: | run: |
docker build --target production -t "ocelotsocialnetwork/webapp:latest" -t "ocelotsocialnetwork/webapp:${VERSION}" -t "ocelotsocialnetwork/webapp:${BUILD_VERSION}" webapp/ docker build --target base -t "ocelotsocialnetwork/webapp:latest-base" -t "ocelotsocialnetwork/webapp:${VERSION}-base" -t "ocelotsocialnetwork/webapp:${BUILD_VERSION}-base" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT webapp/
docker save "ocelotsocialnetwork/webapp" > /tmp/webapp.tar docker build --target code -t "ocelotsocialnetwork/webapp:latest-code" -t "ocelotsocialnetwork/webapp:${VERSION}-code" -t "ocelotsocialnetwork/webapp:${BUILD_VERSION}-code" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT webapp/
docker build --target production -t "ocelotsocialnetwork/webapp:latest" -t "ocelotsocialnetwork/webapp:${VERSION}" -t "ocelotsocialnetwork/webapp:${BUILD_VERSION}" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT webapp/
- name: Webapp | Save docker image
run: docker save "ocelotsocialnetwork/webapp" > /tmp/webapp.tar
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
@ -165,11 +172,13 @@ jobs:
########################################################################## ##########################################################################
# BUILD MAINTENANCE DOCKER IMAGE (build) ################################# # BUILD MAINTENANCE DOCKER IMAGE (build) #################################
########################################################################## ##########################################################################
- name: maintenance | Build `production` image - name: Maintenance | Build `production` image
# TODO: --target production
run: | run: |
docker build -t "ocelotsocialnetwork/maintenance:latest" -t "ocelotsocialnetwork/maintenance:${VERSION}" -t "ocelotsocialnetwork/maintenance:${BUILD_VERSION}" webapp/ -f webapp/Dockerfile.maintenance docker build --target base -t "ocelotsocialnetwork/maintenance:latest-base" -t "ocelotsocialnetwork/maintenance:${VERSION}-base" -t "ocelotsocialnetwork/maintenance:${BUILD_VERSION}-base" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT webapp/ -f webapp/Dockerfile.maintenance
docker save "ocelotsocialnetwork/maintenance" > /tmp/maintenance.tar docker build --target code -t "ocelotsocialnetwork/maintenance:latest-code" -t "ocelotsocialnetwork/maintenance:${VERSION}-code" -t "ocelotsocialnetwork/maintenance:${BUILD_VERSION}-code" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT webapp/ -f webapp/Dockerfile.maintenance
docker build --target production -t "ocelotsocialnetwork/maintenance:latest" -t "ocelotsocialnetwork/maintenance:${VERSION}" -t "ocelotsocialnetwork/maintenance:${BUILD_VERSION}" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT webapp/ -f webapp/Dockerfile.maintenance
- name: Maintenance | Save docker image
run: docker save "ocelotsocialnetwork/maintenance" > /tmp/maintenance.tar
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:

View File

@ -253,7 +253,6 @@ jobs:
########################################################################## ##########################################################################
# COVERAGE REPORT FRONTEND ################################################ # COVERAGE REPORT FRONTEND ################################################
########################################################################## ##########################################################################
# TODO: Maybe remove this later on to avoid spam?
#- name: frontend | Coverage report #- name: frontend | Coverage report
# uses: romeovs/lcov-reporter-action@v0.2.21 # uses: romeovs/lcov-reporter-action@v0.2.21
# with: # with:
@ -268,7 +267,7 @@ jobs:
report_name: Coverage Webapp report_name: Coverage Webapp
type: lcov type: lcov
result_path: ./coverage/lcov.info result_path: ./coverage/lcov.info
min_coverage: 52 min_coverage: 65
token: ${{ github.token }} token: ${{ github.token }}
############################################################################## ##############################################################################

View File

@ -4,11 +4,43 @@ 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). Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
#### [v1.0.2](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/1.0.1...v1.0.2) #### [v1.0.4](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/1.0.3...v1.0.4)
- 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)
- docs: 🍰 Correct 'Contribution.md' [`#4466`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4466)
- docs: 🍰 Correct Discord Links And Divers [`#4461`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4461)
- Implement flexible page footer links [`1bd4af6`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/1bd4af6fd3b5db167575910948a0a72461a1129a)
- Implement tests for flexible page footer links [`627a20f`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/627a20f66a65450996a5fe3128fd37769fdfd629)
- Correct Discord links and divers [`0318910`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/0318910488e245c4a1d09181265de63d05a89cf1)
#### [1.0.3](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/1.0.2...1.0.3)
> 19 May 2021
- chore: 🍰 Release v1.0.3 [`#4435`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4435)
- chore: 🍰 Refactor Logos [`#4433`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4433)
- feat: 🍰 Show Password Component [`#4370`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4370)
- chore: 🍰 Replace Ocelot Logos 619x593 With 600x570 [`#4428`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4428)
- Coverage [`#4393`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4393)
- correct_docker_tagging [`#4391`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4391)
- 🍰 Get Cypress Tests Running Again [`#4338`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4338)
- frontend + backend coverage tests [`#4367`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4367)
- refactor: 🍰 Refactor E-Mail Templates [`#4350`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4350)
- feat: 🍰 Remove More-Info Of Post [`#4316`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4316)
- have cypress running locally - the tests still fail [`e3e0341`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/e3e03415e1bd9e0be88f33930a52e63d8af64ee1)
- have cypress running locally - the tests still fail [`0ec0574`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/0ec05743751cfef0cb86c17b87e9e4ef9a2c9e47)
- Refactor logos, first step [`ff6cc30`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/ff6cc306aff6150a924f1a647387e498d050ea9f)
#### [1.0.2](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/1.0.1...1.0.2)
> 6 April 2021
- fix: Email Confirmation-Link When An Invite-Code Is Given [`#4336`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4336)
- release v1.0.2 [`e583010`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/e5830101e4b449905fe2d0018627d75af62b2a20)
- slider jumps to enter-nonce when link contains invite-code, email and nonce and method is invite-code. Thanks @tirokk [`c80b3a2`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/c80b3a212835f76cfc2f11542345d6c3b226995b) - slider jumps to enter-nonce when link contains invite-code, email and nonce and method is invite-code. Thanks @tirokk [`c80b3a2`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/c80b3a212835f76cfc2f11542345d6c3b226995b)
- fix enail confirmation link when an invite-code is given [`27f0de9`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/27f0de9464685c8f960bde9d07986fdc5b20f8f9) - fix enail confirmation link when an invite-code is given [`27f0de9`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/27f0de9464685c8f960bde9d07986fdc5b20f8f9)
- linting [`21a667e`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/21a667eb25a236c69f69b61f24d1578ea005a910)
#### [1.0.1](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/1.0.0...1.0.1) #### [1.0.1](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/1.0.0...1.0.1)
@ -136,21 +168,11 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- file upload: refactored [`650e83f`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/650e83f4c250389477933a2e7d21d8245b0ce882) - file upload: refactored [`650e83f`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/650e83f4c250389477933a2e7d21d8245b0ce882)
- change user role: tests are working [`14dfe2a`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/14dfe2ae2cd4a24c06c9229893b33586dfceae4f) - change user role: tests are working [`14dfe2a`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/14dfe2ae2cd4a24c06c9229893b33586dfceae4f)
#### [0.6.5](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/v0.6.4...0.6.5) #### [0.6.5](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/0.6.4...0.6.5)
> 8 February 2021 > 8 February 2021
- - adjusted changelog to ocelot-social repo [`9603882`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/9603882edebf8967e05abfa94e4e1ebf452d4e24) - updated CHANGELOG.md [`9d9075f`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/9d9075f2117b2eb4b607e7d59ab18c7e655c6ea7)
- - first steps towards docker image deployment & github autotagging [`5503216`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/5503216ad4a0230ac533042e4a69806590fc2a5a)
- - deploy structure image [`a60400b`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/a60400b4fe6f59bbb80e1073db4def3ba205e1a7)
#### [v0.6.4](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/0.6.4...v0.6.4)
> 9 February 2021
- chore(release): 0.6.4 [`8b7570d`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/8b7570dc35d0ea431f673a711ac051f1e1320acb)
- change user roles is working, test fails [`8c3310a`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/8c3310abaf87c0e5597fec4f93fb37d27122c9e7)
- change user role: tests are working [`f10da4b`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/f10da4b09388fe1e2b85abd53f6ffc67c785d4c1)
#### [0.6.4](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/0.6.3...0.6.4) #### [0.6.4](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/0.6.3...0.6.4)
@ -160,15 +182,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- fetch full history [`5ecee4d`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/5ecee4d73a92d2e5c5ae971d79848ed27f65a72c) - fetch full history [`5ecee4d`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/5ecee4d73a92d2e5c5ae971d79848ed27f65a72c)
- don't fail if tag exists (release) [`39c82fc`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/39c82fcb37d5c8e7e78a79288e1ef6280f8d0892) - don't fail if tag exists (release) [`39c82fc`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/39c82fcb37d5c8e7e78a79288e1ef6280f8d0892)
#### [0.6.3](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/v0.6.3...0.6.3) #### [0.6.3](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/0.6.0...0.6.3)
> 8 February 2021
- - adjusted changelog to ocelot-social repo [`9603882`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/9603882edebf8967e05abfa94e4e1ebf452d4e24)
- - fixed changelog [`cf70b12`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/cf70b12ed74011924ea788ab932fc9d7ac0e6bd9)
- - yarn install to allow yarn auto-changelog [`fc496aa`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/fc496aa04cb7e804da4335da0cb5cda26f874ea2)
#### [v0.6.3](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/0.6.0...v0.6.3)
> 8 February 2021 > 8 February 2021
@ -177,9 +191,9 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- feat: 🍰 Allow Only Supported Image File Formats [`#3928`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/3928) - feat: 🍰 Allow Only Supported Image File Formats [`#3928`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/3928)
- refactor: Disbale Emoji, Language And Catgeory Filter [`#4193`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4193) - refactor: Disbale Emoji, Language And Catgeory Filter [`#4193`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4193)
- refactor: Remove Catgeories From Post Teaser [`#4191`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4191) - refactor: Remove Catgeories From Post Teaser [`#4191`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4191)
- - adjusted changelog to ocelot-social repo [`9603882`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/9603882edebf8967e05abfa94e4e1ebf452d4e24)
- - first steps towards docker image deployment & github autotagging [`5503216`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/5503216ad4a0230ac533042e4a69806590fc2a5a) - - first steps towards docker image deployment & github autotagging [`5503216`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/5503216ad4a0230ac533042e4a69806590fc2a5a)
- - lots of additional tests [`0ba37aa`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/0ba37aab18f537d722aede7b87fa0b8e79f80e66) - - lots of additional tests [`0ba37aa`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/0ba37aab18f537d722aede7b87fa0b8e79f80e66)
- - deploy structure image [`a60400b`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/a60400b4fe6f59bbb80e1073db4def3ba205e1a7)
#### [0.6.0](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/v0.6.0...0.6.0) #### [0.6.0](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/v0.6.0...0.6.0)

View File

@ -4,31 +4,33 @@ Thank you so much for thinking of contributing to the Human Connection project!
## Getting Set Up ## Getting Set Up
Instructions for how to install all the necessary software and some code guidelines can be found in our [documentation](https://docs.human-connection.org/human-connection/). Instructions for how to install all the necessary software and some code guidelines can be found in our main [Readme](/README.md) or in our [documentation](https://docs.human-connection.org/human-connection/).
To get you started we recommend that you join forces with a regular contributor. Please join [our discord instance](https://human-connection.org/discord) to chat with developers or just get in touch directly on an issue on either [Github](https://github.com/Ocelot-Social-Community/Ocelot-Social/issues) or [Zenhub](https://app.zenhub.com/workspaces/ocelotsocial-5fb21ff922cb410015dd6535/board?filterLogic=any&repos=301151089): To get you started we recommend that you join forces with a regular contributor. Please join [our Discord instance](https://discord.gg/AJSX9DCSUA) to chat with developers or just get in touch directly on an issue on either [Github](https://github.com/Ocelot-Social-Community/Ocelot-Social/issues) or [Zenhub](https://app.zenhub.com/workspaces/ocelotsocial-5fb21ff922cb410015dd6535/board?filterLogic=any&repos=301151089):
![](https://dl.dropbox.com/s/vbmcihkduy9dhko/Screenshot%202019-01-03%2015.50.11.png?dl=0) ![](https://dl.dropbox.com/s/vbmcihkduy9dhko/Screenshot%202019-01-03%2015.50.11.png?dl=0)
We also have regular pair programming sessions that you are very welcome to join! We feel this is often the best way to get to know both the project and the team. Most developers are also available for spontaneous sessions if the times listed below don't work for you just ping us on discord. We also have regular pair programming sessions that you are very welcome to join! We feel this is often the best way to get to know both the project and the team. Most developers are also available for spontaneous sessions if the times listed below don't work for you just ping us on Discord.
## Development Flow ## Development Flow
We operate in two week sprints that are planned, estimated and prioritised on [Zenhub](https://app.zenhub.com/workspaces/ocelotsocial-5fb21ff922cb410015dd6535/board?filterLogic=any&repos=301151089). All issues are also linked to and synced with [Github](https://github.com/Ocelot-Social-Community/Ocelot-Social/issues). Look for the `good first issue` label if you're not sure where to start! We operate in two week sprints that are planned, estimated and prioritised on [Zenhub](https://app.zenhub.com/workspaces/ocelotsocial-5fb21ff922cb410015dd6535/board?filterLogic=any&repos=301151089). All issues are also linked to and synced with [Github](https://github.com/Ocelot-Social-Community/Ocelot-Social/issues). Look for the `good first issue` label if you're not sure where to start!
We try to discuss all questions directly related to a feature or bug in the respective issue, in order to preserve it for the future and for other developers. We use discord for real-time communication. We try to discuss all questions directly related to a feature or bug in the respective issue, in order to preserve it for the future and for other developers. We use Discord for real-time communication.
This is how we solve bugs and implement features, step by step: This is how we solve bugs and implement features, step by step:
1. We find an issue we want to work on, usually during the sprint planning but as an open source contributor this can happen at any time. 1. We find an issue we want to work on, usually during the sprint planning but as an open source contributor this can happen at any time.
2. We communicate with the team to see if the issue is still available. (When you comment on an issue but don't get an answer there within 1-2 days try to mention @Human-Connection/hc-dev-team to make sure we check in.) 2. We communicate with the team to see if the issue is still available. (When you comment on an issue but don't get an answer there within 1-2 days try to mention @Human-Connection/hc-dev-team to make sure we check in.)
3. We make sure we understand the issue in detail what problem is it solving and how should it be implemented? 3. We make sure we understand the issue in detail what problem is it solving and how should it be implemented?
4. We assign ourselves to the issue and move it to `In Progress` on [Zenhub](https://app.zenhub.com/workspaces/human-connection-nitro-5c0154ecc699f60fc92cf11f). 4. We assign ourselves to the issue and move it to `In Progress` on [Zenhub](https://app.zenhub.com/workspaces/ocelotsocial-5fb21ff922cb410015dd6535/board?filterLogic=any&repos=301151089).
5. We start working on it in a `new branch` and open a `pull request` prefixed with `[WIP]` (work in progress) to which we regularly push our changes. 5. We start working on it in a `new branch` and open a `pull request` prefixed with `[WIP]` (work in progress) to which we regularly push our changes.
6. When questions come up we clarify them with the team (directly in the issue on Github). 6. When questions come up we clarify them with the team (directly in the issue on Github).
7. When we are happy with our work and our PR is passing all tests we remove the `[WIP]` from the PR description and ask for reviews (if you're not sure who to ask there is @Human-Connection/hc-dev-team which pings all core developers). 7. When we are happy with our work and our PR is passing all tests we remove the `[WIP]` from the PR description and ask for reviews (if you're not sure who to ask there is @Human-Connection/hc-dev-team which pings all core developers).
8. We then incorporate the suggestions from the reviews into our work and once it has been approved it can be merged into master! 8. We then incorporate the suggestions from the reviews into our work and once it has been approved it can be merged into master!
Every pull request needs to: Every pull request needs to:
* fix an issue (if there is something you want to work on but there is no issue for it, create one first and discuss it with the team) * fix an issue (if there is something you want to work on but there is no issue for it, create one first and discuss it with the team)
* include tests for the code that is added or changed * include tests for the code that is added or changed
* pass all tests (linter, backend, frontend, end-to-end) * pass all tests (linter, backend, frontend, end-to-end)
@ -38,37 +40,46 @@ Every pull request needs to:
There are many volunteers all around the world helping us build this network and without their contributions we wouldn't be where we are today. Big thank you to all of you! There are many volunteers all around the world helping us build this network and without their contributions we wouldn't be where we are today. Big thank you to all of you!
You can see the core team behind Human Connection [on our website](https://human-connection.org/en/the-team/). On Github you will mostly run into our developers: You can talk to our core team on [Discord](https://discord.gg/AJSX9DCSUA). And on Github you will mostly run into our core developers:
* Robert (@roschaefer)
* Matt (@mattwr18) * Ulf (@ulfgebhardt)
* Moriz (@Mogge)
* Wolle (@Tirokk) * Wolle (@Tirokk)
* Alex (@ogerly) * Alex (@ogerly)
<!-- * Robert (@roschaefer)
* Matt (@mattwr18)
* Alina (@alina-beck) * Alina (@alina-beck)
* Martin (@datenbrei), our head of IT * Martin (@datenbrei), our head of IT
* and sometimes Dennis (@DennisHack), the founder of Human Connection * and sometimes Dennis (@DennisHack), the founder of Human Connection -->
## Meetings and Pair Programming Sessions ## Meetings and Pair Programming Sessions
Times below refer to **German Time** that's CET (GMT+1) in winter and CEST (GMT+2) in summer because most Human Connection core team members are living in Germany. Times below refer to **German Time** that's CET (GMT+1) in winter and CEST (GMT+2) in summer because most Human Connection core team members are living in Germany.
Daily standup Daily standup
* every MondayFriday 11:30
* in the discord `Conference Room` * every MondayThursday 11:30 am (german time see above 👆🏼)
* in our [Discord](https://discord.gg/AJSX9DCSUA) `Office Cube`
* all contributors welcome! * all contributors welcome!
* everybody shares what they are working on and asks for help if they are blocked * everybody shares what they are working on and asks for help if they are blocked
<!--
Regular pair programming sessions Regular pair programming sessions
* every Monday, Wednesday and Thursday 15:00 * every Monday, Wednesday and Thursday 15:00
* the link will be posted in the [discord chat](https://discord.gg/6ub73U3) and on the [Agile Ventures website](https://www.agileventures.org/events?utf8=%E2%9C%93&project_id=220&commit=Filter+by+Project) * the link will be posted in the [Discord chat](https://discord.gg/AJSX9DCSUA) and on the [Agile Ventures website](https://www.agileventures.org/events?utf8=%E2%9C%93&project_id=220&commit=Filter+by+Project)
* all contributors welcome! * all contributors welcome!
* we team up and work on an issue together (often using Visual Studio live sharing sessions) * we team up and work on an issue together (often using Visual Studio live sharing sessions)
Open-Source Community Meeting Open-Source Community Meeting
* bi-weekly on Mondays 13:00 (when there is no sprint retrospective) * bi-weekly on Mondays 13:00 (when there is no sprint retrospective)
* the link will be posted in the [discord chat](https://discord.gg/6ub73U3) and on the [Agile Ventures website](https://www.agileventures.org/events?utf8=%E2%9C%93&project_id=220&commit=Filter+by+Project) * the link will be posted in the [Discord chat](https://discord.gg/AJSX9DCSUA) and on the [Agile Ventures website](https://www.agileventures.org/events?utf8=%E2%9C%93&project_id=220&commit=Filter+by+Project)
* all contributors welcome! * all contributors welcome!
Meet the team Meet the team
* every Monday 21:00 (at the moment only in German) * every Monday 21:00 (at the moment only in German)
* details here https://human-connection.org/veranstaltungen/ * details here https://human-connection.org/veranstaltungen/
* via this [zoom link](https://zoom.us/j/936943532) * via this [zoom link](https://zoom.us/j/936943532)
@ -76,6 +87,7 @@ Meet the team
* users of the network chat with the Human Connection team and discuss current questions and issues * users of the network chat with the Human Connection team and discuss current questions and issues
Sprint planning Sprint planning
* bi-weekly on Tuesday 13:00 * bi-weekly on Tuesday 13:00
* via this [zoom link](https://zoom.us/j/7743582385) * via this [zoom link](https://zoom.us/j/7743582385)
* all contributors welcome (recommended for those who want to work on an issue in this sprint) * all contributors welcome (recommended for those who want to work on an issue in this sprint)
@ -87,6 +99,7 @@ Sprint retrospective
* via this [zoom link](https://zoom.us/j/7743582385) * via this [zoom link](https://zoom.us/j/7743582385)
* all contributors welcome (most interesting for those who participated in the sprint) * all contributors welcome (most interesting for those who participated in the sprint)
* we review the past sprint and talk about what went well and what we could improve * we review the past sprint and talk about what went well and what we could improve
-->
## Philosophy ## Philosophy
@ -102,10 +115,9 @@ We use pair programming sessions as a tool for knowledge sharing. We can learn a
As a volunteeer you have no commitment except your own self development and your awesomeness by contributing to this free and open-source software project. Cheers to you! As a volunteeer you have no commitment except your own self development and your awesomeness by contributing to this free and open-source software project. Cheers to you!
## Open-Source Bounties ## Open-Source Bounties
There are so many good reasons to contribute to Human Connection There are so many good reasons to contribute to ocelot.social
* You learn state-of-the-art technologies * You learn state-of-the-art technologies
* You build your portfolio * You build your portfolio
@ -121,7 +133,7 @@ pull request approved and merged for free**. You can choose something really
quick and easy. What's important is starting a working relationship with the quick and easy. What's important is starting a working relationship with the
team, learning the workflow, and understanding this contribution guide. You can team, learning the workflow, and understanding this contribution guide. You can
filter issues by 'good first issue', to get an idea where to start. Please join filter issues by 'good first issue', to get an idea where to start. Please join
our our [community chat](https://human-connection.org/discord), too. our our [Discord community chat](https://discord.gg/AJSX9DCSUA), too.
You can filter Github issues with label [bounty](https://github.com/Ocelot-Social-Community/Ocelot-Social/issues?q=is%3Aopen+is%3Aissue+label%3Abounty). These issues should have a second label `€<amount>` You can filter Github issues with label [bounty](https://github.com/Ocelot-Social-Community/Ocelot-Social/issues?q=is%3Aopen+is%3Aissue+label%3Abounty). These issues should have a second label `€<amount>`
which indicate their respective financial compensation in Euros. which indicate their respective financial compensation in Euros.

View File

@ -13,7 +13,7 @@ ocelot.social is a nonprofit social, action and knowledge network that connects
* **Action**: Don't just read about how to make the world a better place, but come into **Action** by following provided suggestions on the **Action** tab provided by other people or **Organisations**. * **Action**: Don't just read about how to make the world a better place, but come into **Action** by following provided suggestions on the **Action** tab provided by other people or **Organisations**.
<p align="center"> <p align="center">
<img src="webapp/static/img/custom/welcome.svg" alt="Ocelot-Social" width="40%" height="40%"> <img src="webapp/static/img/custom/logo-squared.svg" alt="ocelot.social" width="40%" height="40%">
</p> </p>
## Live demo ## Live demo
@ -31,6 +31,7 @@ Logins:
## Directory Layout ## Directory Layout
There are four important directories: There are four important directories:
* [Backend](./backend) runs on the server and is a middleware between database and frontend * [Backend](./backend) runs on the server and is a middleware between database and frontend
* [Frontend](./webapp) is a server-side-rendered and client-side-rendered web frontend * [Frontend](./webapp) is a server-side-rendered and client-side-rendered web frontend
* [Cypress](./cypress) contains end-to-end tests and executable feature specifications * [Cypress](./cypress) contains end-to-end tests and executable feature specifications
@ -46,16 +47,19 @@ There are two approaches:
## Installation ## Installation
### Clone the Repository ### Clone the Repository
Clone the repository, this will create a new folder called `Ocelot-Social`: Clone the repository, this will create a new folder called `Ocelot-Social`:
Using HTTPS: Using HTTPS:
```bash ```bash
$ git clone https://github.com/Ocelot-Social-Community/Ocelot-Social.git $ git clone https://github.com/Ocelot-Social-Community/Ocelot-Social.git
``` ```
Using SSH: Using SSH:
```bash ```bash
$ git clone git@github.com:Human-Connection/Human-Connection.git $ git clone git@github.com:Ocelot-Social-Community/Ocelot-Social.git
``` ```
Change into the new folder. Change into the new folder.
@ -88,13 +92,15 @@ docker-compose version 1.23.2
#### Start Ocelot-Social via Docker-Compose #### Start Ocelot-Social via Docker-Compose
For Development: For Development:
```bash ```bash
docker-compose up $ docker-compose up
``` ```
For Production For Production:
```bash ```bash
docker-compose -f docker-compose.yml up $ docker-compose -f docker-compose.yml up
``` ```
This will start all required Docker containers This will start all required Docker containers
@ -107,12 +113,12 @@ The only deployment method in this repository is `docker-compose` for developmen
## Developer Chat ## Developer Chat
Join our friendly open-source community on [Discord](https://discordapp.com/invite/DFSjPaX) :heart_eyes_cat: Join our friendly open-source community on [Discord](https://discord.gg/AJSX9DCSUA) :heart_eyes_cat:
Just introduce yourself at `#introduce-yourself` and mention `@@Mentor` to get you onboard :neckbeard: Just introduce yourself at `#introduce-yourself` and mention `@@Mentor` to get you onboard :neckbeard:
Check out the [contribution guideline](./CONTRIBUTING.md), too! Check out the [contribution guideline](./CONTRIBUTING.md), too!
We give write permissions to every developer who asks for it. Just text us on We give write permissions to every developer who asks for it. Just text us on
[Discord](https://discord.gg/6ub73U3). [Discord](https://discord.gg/AJSX9DCSUA).
## Technology Stack ## Technology Stack
@ -131,4 +137,5 @@ Browser compatibility testing with [BrowserStack](https://www.browserstack.com/)
<img alt="BrowserStack Logo" src=".gitbook/assets/browserstack-logo.svg" width="256"> <img alt="BrowserStack Logo" src=".gitbook/assets/browserstack-logo.svg" width="256">
## License ## License
See the [LICENSE](LICENSE.md) file for license rights and limitations (MIT). See the [LICENSE](LICENSE.md) file for license rights and limitations (MIT).

View File

@ -1,17 +1,20 @@
################################################################################## ##################################################################################
# BASE ########################################################################### # BASE (Is pushed to DockerHub for rebranding) ###################################
################################################################################## ##################################################################################
FROM node:12.19.0-alpine3.10 as base FROM node:12.19.0-alpine3.10 as base
# ENVs (available in production aswell, can be overwritten by commandline or env file) # ENVs
## DOCKER_WORKDIR would be a classical ARG, but that is not multi layer persistent - shame ## DOCKER_WORKDIR would be a classical ARG, but that is not multi layer persistent - shame
ENV DOCKER_WORKDIR="/app" ENV DOCKER_WORKDIR="/app"
## We Cannot do `$(date -u +'%Y-%m-%dT%H:%M:%SZ')` here so we use unix timestamp=0 ## We Cannot do `$(date -u +'%Y-%m-%dT%H:%M:%SZ')` here so we use unix timestamp=0
ENV BUILD_DATE="1970-01-01T00:00:00.00Z" ARG BBUILD_DATE="1970-01-01T00:00:00.00Z"
ENV BUILD_DATE=$BBUILD_DATE
## We cannot do $(yarn run version)-${BUILD_NUMBER} here so we default to 0.0.0-0 ## We cannot do $(yarn run version)-${BUILD_NUMBER} here so we default to 0.0.0-0
ENV BUILD_VERSION="0.0.0-0" ARG BBUILD_VERSION="0.0.0-0"
ENV BUILD_VERSION=$BBUILD_VERSION
## We cannot do `$(git rev-parse --short HEAD)` here so we default to 0000000 ## We cannot do `$(git rev-parse --short HEAD)` here so we default to 0000000
ENV BUILD_COMMIT="0000000" ARG BBUILD_COMMIT="0000000"
ENV BUILD_COMMIT=$BBUILD_COMMIT
## SET NODE_ENV ## SET NODE_ENV
ENV NODE_ENV="production" ENV NODE_ENV="production"
## App relevant Envs ## App relevant Envs
@ -56,12 +59,18 @@ FROM base as development
CMD /bin/sh -c "yarn install && yarn run dev" CMD /bin/sh -c "yarn install && yarn run dev"
################################################################################## ##################################################################################
# BUILD (Does contain all files and is therefore bloated) ######################## # CODE (Does contain all code files and is pushed to DockerHub for rebranding) ###
################################################################################## ##################################################################################
FROM base as build FROM base as code
# Copy everything # copy everything, but do not build.
COPY . . COPY . .
##################################################################################
# BUILD (Does contain all files and the compilate and is therefore bloated) ######
##################################################################################
FROM code as build
# yarn install # yarn install
RUN yarn install --production=false --frozen-lockfile --non-interactive RUN yarn install --production=false --frozen-lockfile --non-interactive
# yarn build # yarn build
@ -82,7 +91,6 @@ FROM base as production
# Copy "binary"-files from build image # Copy "binary"-files from build image
COPY --from=build ${DOCKER_WORKDIR}/dist ./dist COPY --from=build ${DOCKER_WORKDIR}/dist ./dist
COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules
# Copy static files # Copy static files
# TODO - externalize the uploads so we can copy the whole folder # TODO - externalize the uploads so we can copy the whole folder
COPY --from=build ${DOCKER_WORKDIR}/public/img/ ./public/img/ COPY --from=build ${DOCKER_WORKDIR}/public/img/ ./public/img/

View File

@ -1,6 +1,6 @@
{ {
"name": "ocelot-social-backend", "name": "ocelot-social-backend",
"version": "1.0.2", "version": "1.0.4",
"description": "GraphQL Backend for ocelot.social", "description": "GraphQL Backend for ocelot.social",
"repository": "https://github.com/Ocelot-Social-Community/Ocelot-Social", "repository": "https://github.com/Ocelot-Social-Community/Ocelot-Social",
"author": "ocelot.social Community", "author": "ocelot.social Community",
@ -39,6 +39,12 @@
] ]
}, },
"dependencies": { "dependencies": {
"@babel/cli": "~7.8.4",
"@babel/core": "~7.9.0",
"@babel/node": "~7.8.7",
"@babel/plugin-proposal-throw-expressions": "^7.8.3",
"@babel/preset-env": "~7.9.5",
"@babel/register": "^7.9.0",
"@hapi/joi": "^17.1.1", "@hapi/joi": "^17.1.1",
"@sentry/node": "^5.15.4", "@sentry/node": "^5.15.4",
"apollo-cache-inmemory": "~1.6.5", "apollo-cache-inmemory": "~1.6.5",
@ -48,6 +54,9 @@
"apollo-server": "~2.14.2", "apollo-server": "~2.14.2",
"apollo-server-express": "^2.14.2", "apollo-server-express": "^2.14.2",
"aws-sdk": "^2.652.0", "aws-sdk": "^2.652.0",
"babel-core": "~7.0.0-0",
"babel-eslint": "~10.1.0",
"babel-jest": "~25.2.6",
"babel-plugin-transform-runtime": "^6.23.0", "babel-plugin-transform-runtime": "^6.23.0",
"bcryptjs": "~2.4.3", "bcryptjs": "~2.4.3",
"cheerio": "~1.0.0-rc.3", "cheerio": "~1.0.0-rc.3",
@ -72,7 +81,7 @@
"languagedetect": "^2.0.0", "languagedetect": "^2.0.0",
"linkifyjs": "~2.1.8", "linkifyjs": "~2.1.8",
"lodash": "~4.17.14", "lodash": "~4.17.14",
"merge-graphql-schemas": "^1.7.7", "merge-graphql-schemas": "^1.7.8",
"metascraper": "^5.11.8", "metascraper": "^5.11.8",
"metascraper-audio": "^5.14.26", "metascraper-audio": "^5.14.26",
"metascraper-author": "^5.14.22", "metascraper-author": "^5.14.22",
@ -111,16 +120,7 @@
"xregexp": "^4.3.0" "xregexp": "^4.3.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "~7.8.4",
"@babel/core": "~7.9.0",
"@babel/node": "~7.8.7",
"@babel/plugin-proposal-throw-expressions": "^7.8.3",
"@babel/preset-env": "~7.9.5",
"@babel/register": "^7.9.0",
"apollo-server-testing": "~2.11.0", "apollo-server-testing": "~2.11.0",
"babel-core": "~7.0.0-0",
"babel-eslint": "~10.1.0",
"babel-jest": "~25.2.6",
"chai": "~4.2.0", "chai": "~4.2.0",
"cucumber": "~6.0.5", "cucumber": "~6.0.5",
"eslint": "~6.8.0", "eslint": "~6.8.0",
@ -134,7 +134,7 @@
"eslint-plugin-standard": "~4.0.1", "eslint-plugin-standard": "~4.0.1",
"jest": "~25.3.0", "jest": "~25.3.0",
"nodemon": "~2.0.2", "nodemon": "~2.0.2",
"prettier": "~2.2.0", "prettier": "~2.3.2",
"rosie": "^2.0.1", "rosie": "^2.0.1",
"supertest": "~4.0.2" "supertest": "~4.0.2"
}, },

View File

@ -40,8 +40,8 @@ const server = {
const smtp = { const smtp = {
SMTP_HOST: env.SMTP_HOST, SMTP_HOST: env.SMTP_HOST,
SMTP_PORT: env.SMTP_PORT, SMTP_PORT: env.SMTP_PORT,
SMTP_IGNORE_TLS: env.SMTP_IGNORE_TLS === 'true' || true, SMTP_IGNORE_TLS: env.SMTP_IGNORE_TLS !== 'false', // default = true
SMTP_SECURE: env.SMTP_IGNORE_TLS === 'true' || false, SMTP_SECURE: env.SMTP_SECURE === 'true',
SMTP_USERNAME: env.SMTP_USERNAME, SMTP_USERNAME: env.SMTP_USERNAME,
SMTP_PASSWORD: env.SMTP_PASSWORD, SMTP_PASSWORD: env.SMTP_PASSWORD,
} }

View File

@ -1,6 +1,13 @@
// this file is duplicated in `backend/src/config/links.js` and `webapp/constants/links.js` and replaced on rebranding
export default { export default {
ORGANIZATION: 'https://ocelot.social', ORGANIZATION: 'https://ocelot.social',
DONATE: 'https://ocelot-social.herokuapp.com/donations',
FAQ: 'https://ocelot.social',
SUPPORT: 'https://ocelot.social', SUPPORT: 'https://ocelot.social',
// on null or empty strings internal imprint is used, see 'webapp/locales/html/'
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

@ -0,0 +1,10 @@
// this file is duplicated in `backend/src/config/logos.js` 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',
LOGO_SIGNUP_PATH: '/img/custom/logo-squared.svg',
LOGO_WELCOME_PATH: '/img/custom/logo-squared.svg',
LOGO_LOGOUT_PATH: '/img/custom/logo-squared.svg',
LOGO_PASSWORD_RESET_PATH: '/img/custom/logo-squared.svg',
LOGO_MAINTENACE_RESET_PATH: '/img/custom/logo-squared.svg',
}

View File

@ -1,7 +1,9 @@
// this file is duplicated in `backend/src/config/metadata.js` and `webapp/constants/metadata.js` and replaced on rebranding
export default { export default {
APPLICATION_NAME: 'ocelot.social', APPLICATION_NAME: 'ocelot.social',
APPLICATION_SHORT_NAME: 'ocelot', APPLICATION_SHORT_NAME: 'ocelot',
APPLICATION_DESCRIPTION: 'ocelot.social Community Network', APPLICATION_DESCRIPTION: 'ocelot.social Community Network',
COOKIE_NAME: 'ocelot-social-token',
ORGANIZATION_NAME: 'ocelot.social Community', ORGANIZATION_NAME: 'ocelot.social Community',
ORGANIZATION_JURISDICTION: 'City of Angels', ORGANIZATION_JURISDICTION: 'City of Angels',
} }

View File

@ -137,15 +137,8 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
}), }),
]) ])
const [ const [peterLustig, bobDerBaumeister, jennyRostock, huey, dewey, louie, dagobert] =
peterLustig, await Promise.all([
bobDerBaumeister,
jennyRostock,
huey,
dewey,
louie,
dagobert,
] = await Promise.all([
Factory.build( Factory.build(
'user', 'user',
{ {

View File

@ -1,10 +1,11 @@
import mustache from 'mustache' import mustache from 'mustache'
import CONFIG from '../../config' import CONFIG from '../../config'
import logosWebapp from '../../config/logos.js'
import * as templates from './templates' import * as templates from './templates'
const from = CONFIG.EMAIL_DEFAULT_SENDER const from = CONFIG.EMAIL_DEFAULT_SENDER
const welcomeImageUrl = new URL(`/img/custom/welcome.svg`, CONFIG.CLIENT_URI) const welcomeImageUrl = new URL(logosWebapp.LOGO_WELCOME_PATH, CONFIG.CLIENT_URI)
const defaultParams = { const defaultParams = {
supportUrl: CONFIG.SUPPORT_URL, supportUrl: CONFIG.SUPPORT_URL,

View File

@ -37,8 +37,7 @@ const babyLovesCatEmbedResponse = new Response(
thumbnail_height: 360, thumbnail_height: 360,
provider_url: 'https://www.youtube.com/', provider_url: 'https://www.youtube.com/',
thumbnail_width: 480, thumbnail_width: 480,
html: html: '<iframe width="480" height="270" src="https://www.youtube.com/embed/qkdXAtO40Fo?start=18&feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>',
'<iframe width="480" height="270" src="https://www.youtube.com/embed/qkdXAtO40Fo?start=18&feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>',
thumbnail_url: 'https://i.ytimg.com/vi/qkdXAtO40Fo/hqdefault.jpg', thumbnail_url: 'https://i.ytimg.com/vi/qkdXAtO40Fo/hqdefault.jpg',
version: '1.0', version: '1.0',
author_name: 'Merkley Family', author_name: 'Merkley Family',
@ -204,8 +203,7 @@ Have all the information for the brand in separate config files. Set these defau
video: null, video: null,
lang: 'de', lang: 'de',
sources: ['resource', 'oembed'], sources: ['resource', 'oembed'],
html: html: '<iframe width="480" height="270" src="https://www.youtube.com/embed/qkdXAtO40Fo?start=18&feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>',
'<iframe width="480" height="270" src="https://www.youtube.com/embed/qkdXAtO40Fo?start=18&feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>',
}, },
}, },
errors: undefined, errors: undefined,

View File

@ -910,6 +910,13 @@
dependencies: dependencies:
regenerator-runtime "^0.13.4" regenerator-runtime "^0.13.4"
"@babel/runtime@^7.9.2":
version "7.12.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e"
integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==
dependencies:
regenerator-runtime "^0.13.4"
"@babel/template@^7.7.4", "@babel/template@^7.8.3", "@babel/template@^7.8.6": "@babel/template@^7.7.4", "@babel/template@^7.8.3", "@babel/template@^7.8.6":
version "7.8.6" version "7.8.6"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b"
@ -956,32 +963,32 @@
exec-sh "^0.3.2" exec-sh "^0.3.2"
minimist "^1.2.0" minimist "^1.2.0"
"@graphql-toolkit/common@0.9.12": "@graphql-toolkit/common@0.10.4":
version "0.9.12" version "0.10.4"
resolved "https://registry.yarnpkg.com/@graphql-toolkit/common/-/common-0.9.12.tgz#a3bf91d00130100cfa0a72be718b16cc1011ab45" resolved "https://registry.yarnpkg.com/@graphql-toolkit/common/-/common-0.10.4.tgz#7785f2a3f14559d0778859c49f4442078c196695"
integrity sha512-NjBVxeM1GB0bldiBm4UQoxKtbu/hjRfcqDEt1JPia+uXgFde3qTxtF5IZkworRFNCp+8KPSVrwcreQHSfFW63w== integrity sha512-HQ3HaxCqX+UE8y/0h7LMDBBGSIKJxY/gaQesaksvE2Y+N4NpSWdiW6HpOcgXfC2HGf9yM0hEdsERzzL8z3mbHQ==
dependencies: dependencies:
aggregate-error "3.0.1" aggregate-error "3.0.1"
camel-case "4.1.1" camel-case "4.1.1"
graphql-tools-fork "9.0.1" graphql-tools "5.0.0"
lodash "4.17.15" lodash "4.17.15"
"@graphql-toolkit/file-loading@0.9.12": "@graphql-toolkit/file-loading@0.10.4":
version "0.9.12" version "0.10.4"
resolved "https://registry.yarnpkg.com/@graphql-toolkit/file-loading/-/file-loading-0.9.12.tgz#f7d5d7e042df59c4e6c8fe3417c67dd1cddf9043" resolved "https://registry.yarnpkg.com/@graphql-toolkit/file-loading/-/file-loading-0.10.4.tgz#50e8933e44b17853544c1fe63350df93f33a5e80"
integrity sha512-xEmKkbWI5FXQARTN3dbPzshwcmduOJUvx1QGsfcuryVDdQJZynUEaPF7IxYaFpvQF7vwxGIRdff/jC/a5ypDrA== integrity sha512-oUmy/sO3BJfax85pVKI7FZ6TWrViNuWXoJkRM293YV9bKGuYU9TgqZoHyM+oEqWO5ruXCL/nCdw3cIBau+rSNA==
dependencies: dependencies:
globby "11.0.0" globby "11.0.0"
unixify "1.0.0" unixify "1.0.0"
"@graphql-toolkit/schema-merging@0.9.12": "@graphql-toolkit/schema-merging@0.10.4":
version "0.9.12" version "0.10.4"
resolved "https://registry.yarnpkg.com/@graphql-toolkit/schema-merging/-/schema-merging-0.9.12.tgz#f058a7d256a4ed0e61e9874f90ae03326b81668e" resolved "https://registry.yarnpkg.com/@graphql-toolkit/schema-merging/-/schema-merging-0.10.4.tgz#2428590a531a33e9fe03be27cce9030f1c4c044b"
integrity sha512-ciqxLeMw7KPbJcq/xgnPbGyJGRO6bO1zQcdWCUSssyw8VDRHj5PFqEOAzT88eZQkEtg3qLN/wQEypeyFyNTHzw== integrity sha512-naL6reYBuILLMrkMfKz0lOLL0kl6gGYnaaywnO/Dgp9F4NeAxDdAs5CV6Fy9NO5OzePFP58Dnc4sh2RyYrrFJg==
dependencies: dependencies:
"@graphql-toolkit/common" "0.9.12" "@graphql-toolkit/common" "0.10.4"
deepmerge "4.2.2" deepmerge "4.2.2"
graphql-tools-fork "9.0.1" graphql-tools "5.0.0"
tslib "1.11.1" tslib "1.11.1"
"@hapi/address@2.x.x": "@hapi/address@2.x.x":
@ -2036,7 +2043,7 @@ apollo-link-context@~1.0.20:
apollo-link "^1.2.14" apollo-link "^1.2.14"
tslib "^1.9.3" tslib "^1.9.3"
apollo-link-http-common@^0.2.15, apollo-link-http-common@^0.2.16: apollo-link-http-common@^0.2.14, apollo-link-http-common@^0.2.16:
version "0.2.16" version "0.2.16"
resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.16.tgz#756749dafc732792c8ca0923f9a40564b7c59ecc" resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.16.tgz#756749dafc732792c8ca0923f9a40564b7c59ecc"
integrity sha512-2tIhOIrnaF4UbQHf7kjeQA/EmSorB7+HyJIIrUjJOKBgnXwuexi8aMecRlqTIDWcyVXCeqLhUnztMa6bOH/jTg== integrity sha512-2tIhOIrnaF4UbQHf7kjeQA/EmSorB7+HyJIIrUjJOKBgnXwuexi8aMecRlqTIDWcyVXCeqLhUnztMa6bOH/jTg==
@ -2054,7 +2061,7 @@ apollo-link-http@~1.5.17:
apollo-link-http-common "^0.2.16" apollo-link-http-common "^0.2.16"
tslib "^1.9.3" tslib "^1.9.3"
apollo-link@^1.0.0, apollo-link@^1.2.13, apollo-link@^1.2.14: apollo-link@^1.0.0, apollo-link@^1.2.12, apollo-link@^1.2.14:
version "1.2.14" version "1.2.14"
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.14.tgz#3feda4b47f9ebba7f4160bef8b977ba725b684d9" resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.14.tgz#3feda4b47f9ebba7f4160bef8b977ba725b684d9"
integrity sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg== integrity sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg==
@ -2211,6 +2218,16 @@ apollo-tracing@^0.12.0:
apollo-server-env "^2.4.5" apollo-server-env "^2.4.5"
apollo-server-plugin-base "^0.10.2" apollo-server-plugin-base "^0.10.2"
apollo-upload-client@^13.0.0:
version "13.0.0"
resolved "https://registry.yarnpkg.com/apollo-upload-client/-/apollo-upload-client-13.0.0.tgz#146d1ddd85d711fcac8ca97a72d3ca6787f2b71b"
integrity sha512-lJ9/bk1BH1lD15WhWRha2J3+LrXrPIX5LP5EwiOUHv8PCORp4EUrcujrA3rI5hZeZygrTX8bshcuMdpqpSrvtA==
dependencies:
"@babel/runtime" "^7.9.2"
apollo-link "^1.2.12"
apollo-link-http-common "^0.2.14"
extract-files "^8.0.0"
apollo-utilities@1.3.3, apollo-utilities@^1.3.3: apollo-utilities@1.3.3, apollo-utilities@^1.3.3:
version "1.3.3" version "1.3.3"
resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.3.3.tgz#f1854715a7be80cd810bc3ac95df085815c0787c" resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.3.3.tgz#f1854715a7be80cd810bc3ac95df085815c0787c"
@ -4299,10 +4316,10 @@ extglob@^2.0.4:
snapdragon "^0.8.1" snapdragon "^0.8.1"
to-regex "^3.0.1" to-regex "^3.0.1"
extract-files@^7.0.0: extract-files@^8.0.0:
version "7.0.0" version "8.1.0"
resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-7.0.0.tgz#3dc7853320ff7876ec62d6e98f2f4e6f3e6282f6" resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-8.1.0.tgz#46a0690d0fe77411a2e3804852adeaa65cd59288"
integrity sha512-3AUlT7TD+DbQXNe3t70QrgJU6Wgcp7rk1Zm0vqWz8OYnw4vxihgG0TgZ2SIGrVqScc4WfOu7B4a0BezGJ0YqvQ== integrity sha512-PTGtfthZK79WUMk+avLmwx3NGdU8+iVFXC2NMGxKsn0MnihOG2lvumj+AZo8CTwTrwjXDgZ5tztbRlEdRjBonQ==
extsprintf@1.3.0: extsprintf@1.3.0:
version "1.3.0" version "1.3.0"
@ -4849,19 +4866,19 @@ graphql-tag@^2.9.2, graphql-tag@~2.10.3:
resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.3.tgz#ea1baba5eb8fc6339e4c4cf049dabe522b0edf03" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.3.tgz#ea1baba5eb8fc6339e4c4cf049dabe522b0edf03"
integrity sha512-4FOv3ZKfA4WdOKJeHdz6B3F/vxBLSgmBcGeAFPf4n1F64ltJUvOOerNj0rsJxONQGdhUMynQIvd6LzB+1J5oKA== integrity sha512-4FOv3ZKfA4WdOKJeHdz6B3F/vxBLSgmBcGeAFPf4n1F64ltJUvOOerNj0rsJxONQGdhUMynQIvd6LzB+1J5oKA==
graphql-tools-fork@9.0.1: graphql-tools@5.0.0:
version "9.0.1" version "5.0.0"
resolved "https://registry.yarnpkg.com/graphql-tools-fork/-/graphql-tools-fork-9.0.1.tgz#fc8df40c108bdba3268999dea355cc614c765038" resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-5.0.0.tgz#67281c834a0e29f458adba8018f424816fa627e9"
integrity sha512-kM6mUNVekgnWKtVqLGQ9HvQqQ3zZVPZRg1esltBoohsbUMaChl+9QkjBjoMxnZPnbTGOOGGagopNBQALIBysNg== integrity sha512-5zn3vtn//382b7G3Wzz3d5q/sh+f7tVrnxeuhTMTJ7pWJijNqLxH7VEzv8VwXCq19zAzHYEosFHfXiK7qzvk7w==
dependencies: dependencies:
apollo-link "^1.2.13" apollo-link "^1.2.14"
apollo-link-http-common "^0.2.15" apollo-upload-client "^13.0.0"
deprecated-decorator "^0.1.6" deprecated-decorator "^0.1.6"
extract-files "^7.0.0"
form-data "^3.0.0" form-data "^3.0.0"
iterall "^1.3.0" iterall "^1.3.0"
node-fetch "^2.6.0" node-fetch "^2.6.0"
uuid "^7.0.2" tslib "^1.11.1"
uuid "^7.0.3"
graphql-tools@^4.0.0, graphql-tools@^4.0.4, graphql-tools@^4.0.5: graphql-tools@^4.0.0, graphql-tools@^4.0.4, graphql-tools@^4.0.5:
version "4.0.8" version "4.0.8"
@ -6606,13 +6623,13 @@ merge-descriptors@1.0.1:
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
merge-graphql-schemas@^1.7.7: merge-graphql-schemas@^1.7.8:
version "1.7.7" version "1.7.8"
resolved "https://registry.yarnpkg.com/merge-graphql-schemas/-/merge-graphql-schemas-1.7.7.tgz#673898f97c384d88fd66e49359b2f604e5864441" resolved "https://registry.yarnpkg.com/merge-graphql-schemas/-/merge-graphql-schemas-1.7.8.tgz#11a0a672a38a61d988c09ffdebe1bd4f8418de48"
integrity sha512-3mjFHXpsF+bnsnSy/FlZiWCcNo7AULuG8kEBE+YVX8qbzNrEPJVhSg7ANr5LjQZbGtSlTz7fa3Wqw0bfbQ5R5Q== integrity sha512-C3EJ1i86OjmbcCT524wVPRl17M5VZzgyh9kIGYAlYnAILX+7xfh8cCbMKfehh9n4opZg6CtcPogCiVZ6PB2NyQ==
dependencies: dependencies:
"@graphql-toolkit/file-loading" "0.9.12" "@graphql-toolkit/file-loading" "0.10.4"
"@graphql-toolkit/schema-merging" "0.9.12" "@graphql-toolkit/schema-merging" "0.10.4"
tslib "1.11.1" tslib "1.11.1"
merge-stream@^2.0.0: merge-stream@^2.0.0:
@ -7816,10 +7833,10 @@ prettier-linter-helpers@^1.0.0:
dependencies: dependencies:
fast-diff "^1.1.2" fast-diff "^1.1.2"
prettier@~2.2.0: prettier@~2.3.2:
version "2.2.0" version "2.3.2"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.0.tgz#8a03c7777883b29b37fb2c4348c66a78e980418b" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d"
integrity sha512-yYerpkvseM4iKD/BXLYUkQV5aKt4tQPqaGW6EsZjzyu0r7sVZZNPJW4Y8MyKmicp6t42XUPcBVA+H6sB3gqndw== integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==
pretty-format@^25.3.0: pretty-format@^25.3.0:
version "25.3.0" version "25.3.0"
@ -9406,15 +9423,15 @@ ts-invariant@^0.4.0:
dependencies: dependencies:
tslib "^1.9.3" tslib "^1.9.3"
tslib@1.11.1, tslib@^1.9.0: tslib@1.11.1:
version "1.11.1" version "1.11.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==
tslib@^1.10.0, tslib@^1.9.3: tslib@^1.10.0, tslib@^1.11.1, tslib@^1.9.0, tslib@^1.9.3:
version "1.13.0" version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tunnel-agent@^0.6.0: tunnel-agent@^0.6.0:
version "0.6.0" version "0.6.0"
@ -9689,7 +9706,7 @@ uuid@^3.1.0, uuid@^3.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^7.0.2: uuid@^7.0.3:
version "7.0.3" version "7.0.3"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b"
integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==

View File

@ -18,7 +18,6 @@ services:
- webapp_node_modules:/app/node_modules - webapp_node_modules:/app/node_modules
# bind the local folder to the docker to allow live reload # bind the local folder to the docker to allow live reload
- ./webapp:/app - ./webapp:/app
######################################################## ########################################################
# BACKEND ############################################## # BACKEND ##############################################
######################################################## ########################################################
@ -35,7 +34,6 @@ services:
- backend_node_modules:/app/node_modules - backend_node_modules:/app/node_modules
# bind the local folder to the docker to allow live reload # bind the local folder to the docker to allow live reload
- ./backend:/app - ./backend:/app
######################################################## ########################################################
# NEO4J ################################################ # NEO4J ################################################
######################################################## ########################################################
@ -47,13 +45,11 @@ services:
networks: networks:
# So we can access the neo4j query browser from our host machine # So we can access the neo4j query browser from our host machine
- external-net - external-net
######################################################## ########################################################
# MAINTENANCE ########################################## # MAINTENANCE ##########################################
######################################################## ########################################################
maintenance: maintenance:
image: ocelotsocialnetwork/maintenance:development image: ocelotsocialnetwork/maintenance:development
######################################################## ########################################################
# MAILSERVER TO FAKE SMTP ############################## # MAILSERVER TO FAKE SMTP ##############################
######################################################## ########################################################
@ -63,6 +59,7 @@ services:
- 1080:80 - 1080:80
networks: networks:
- external-net - external-net
volumes: volumes:
webapp_node_modules: webapp_node_modules:
backend_node_modules: backend_node_modules:

View File

@ -12,7 +12,6 @@ services:
- NODE_ENV="test" - NODE_ENV="test"
volumes: volumes:
- ./coverage:/app/coverage - ./coverage:/app/coverage
######################################################## ########################################################
# BACKEND ############################################## # BACKEND ##############################################
######################################################## ########################################################
@ -24,7 +23,6 @@ services:
- NODE_ENV="test" - NODE_ENV="test"
volumes: volumes:
- ./coverage:/app/coverage - ./coverage:/app/coverage
######################################################## ########################################################
# NEO4J ################################################ # NEO4J ################################################
######################################################## ########################################################
@ -41,13 +39,11 @@ services:
networks: networks:
# So we can access the neo4j query browser from our host machine # So we can access the neo4j query browser from our host machine
- external-net - external-net
######################################################## ########################################################
# MAINTENANCE ########################################## # MAINTENANCE ##########################################
######################################################## ########################################################
maintenance: maintenance:
image: ocelotsocialnetwork/maintenance:test image: ocelotsocialnetwork/maintenance:test
######################################################## ########################################################
# MAILSERVER TO FAKE SMTP ############################## # MAILSERVER TO FAKE SMTP ##############################
######################################################## ########################################################
@ -57,6 +53,7 @@ services:
- 1080:80 - 1080:80
networks: networks:
- external-net - external-net
volumes: volumes:
webapp_node_modules: webapp_node_modules:
backend_node_modules: backend_node_modules:

View File

@ -35,7 +35,6 @@ services:
- GRAPHQL_URI=http://backend:4000 - GRAPHQL_URI=http://backend:4000
env_file: env_file:
- ./webapp/.env - ./webapp/.env
######################################################## ########################################################
# BACKEND ############################################## # BACKEND ##############################################
######################################################## ########################################################
@ -68,7 +67,6 @@ services:
- CLIENT_URI=http://webapp:3000 - CLIENT_URI=http://webapp:3000
env_file: env_file:
- ./backend/.env - ./backend/.env
######################################################## ########################################################
# NEO4J ################################################ # NEO4J ################################################
######################################################## ########################################################
@ -92,7 +90,6 @@ services:
# TODO: clarify if that is the only thing needed to unlock the Enterprise version # TODO: clarify if that is the only thing needed to unlock the Enterprise version
# - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes # - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
# TODO: Remove the playground from production # TODO: Remove the playground from production
######################################################## ########################################################
# MAINTENANCE ########################################## # MAINTENANCE ##########################################
######################################################## ########################################################

View File

@ -3,13 +3,16 @@
################################################################################## ##################################################################################
FROM neo4j:3.5.14 as community FROM neo4j:3.5.14 as community
# ENVs (available in production aswell, can be overwritten by commandline or env file) # ENVs
## We Cannot do `$(date -u +'%Y-%m-%dT%H:%M:%SZ')` here so we use unix timestamp=0 ## We Cannot do `$(date -u +'%Y-%m-%dT%H:%M:%SZ')` here so we use unix timestamp=0
ENV BUILD_DATE="1970-01-01T00:00:00.00Z" ARG BBUILD_DATE="1970-01-01T00:00:00.00Z"
ENV BUILD_DATE=$BBUILD_DATE
## We cannot do $(yarn run version)-${BUILD_NUMBER} here so we default to 0.0.0-0 ## We cannot do $(yarn run version)-${BUILD_NUMBER} here so we default to 0.0.0-0
ENV BUILD_VERSION="0.0.0-0" ARG BBUILD_VERSION="0.0.0-0"
ENV BUILD_VERSION=$BBUILD_VERSION
## We cannot do `$(git rev-parse --short HEAD)` here so we default to 0000000 ## We cannot do `$(git rev-parse --short HEAD)` here so we default to 0000000
ENV BUILD_COMMIT="0000000" ARG BBUILD_COMMIT="0000000"
ENV BUILD_COMMIT=$BBUILD_COMMIT
# Labels # Labels
LABEL org.label-schema.build-date="${BUILD_DATE}" LABEL org.label-schema.build-date="${BUILD_DATE}"

View File

@ -1,6 +1,6 @@
{ {
"name": "ocelot-social", "name": "ocelot-social",
"version": "1.0.2", "version": "1.0.4",
"description": "Fullstack and API tests with cypress and cucumber for ocelot.social", "description": "Fullstack and API tests with cypress and cucumber for ocelot.social",
"author": "ocelot.social Community", "author": "ocelot.social Community",
"license": "MIT", "license": "MIT",
@ -37,7 +37,7 @@
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"expect": "^25.3.0", "expect": "^25.3.0",
"faker": "Marak/faker.js#master", "faker": "Marak/faker.js#master",
"graphql-request": "^1.8.2", "graphql-request": "^2.0.0",
"import": "^0.0.6", "import": "^0.0.6",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"mock-socket": "^9.0.3", "mock-socket": "^9.0.3",
@ -49,5 +49,6 @@
}, },
"resolutions": { "resolutions": {
"set-value": "^2.0.1" "set-value": "^2.0.1"
} },
"dependencies": {}
} }

View File

@ -1,17 +1,20 @@
################################################################################## ##################################################################################
# BASE ########################################################################### # BASE (Is pushed to DockerHub for rebranding) ###################################
################################################################################## ##################################################################################
FROM node:12.19.0-alpine3.10 as base FROM node:12.19.0-alpine3.10 as base
# ENVs (available in production aswell, can be overwritten by commandline or env file) # ENVs
## DOCKER_WORKDIR would be a classical ARG, but that is not multi layer persistent - shame ## DOCKER_WORKDIR would be a classical ARG, but that is not multi layer persistent - shame
ENV DOCKER_WORKDIR="/app" ENV DOCKER_WORKDIR="/app"
## We Cannot do `$(date -u +'%Y-%m-%dT%H:%M:%SZ')` here so we use unix timestamp=0 ## We Cannot do `$(date -u +'%Y-%m-%dT%H:%M:%SZ')` here so we use unix timestamp=0
ENV BUILD_DATE="1970-01-01T00:00:00.00Z" ARG BBUILD_DATE="1970-01-01T00:00:00.00Z"
ENV BUILD_DATE=$BBUILD_DATE
## We cannot do $(yarn run version)-${BUILD_NUMBER} here so we default to 0.0.0-0 ## We cannot do $(yarn run version)-${BUILD_NUMBER} here so we default to 0.0.0-0
ENV BUILD_VERSION="0.0.0-0" ARG BBUILD_VERSION="0.0.0-0"
ENV BUILD_VERSION=$BBUILD_VERSION
## We cannot do `$(git rev-parse --short HEAD)` here so we default to 0000000 ## We cannot do `$(git rev-parse --short HEAD)` here so we default to 0000000
ENV BUILD_COMMIT="0000000" ARG BBUILD_COMMIT="0000000"
ENV BUILD_COMMIT=$BBUILD_COMMIT
## SET NODE_ENV ## SET NODE_ENV
ENV NODE_ENV="production" ENV NODE_ENV="production"
## App relevant Envs ## App relevant Envs
@ -56,12 +59,18 @@ FROM base as development
CMD /bin/sh -c "yarn install && yarn run dev" CMD /bin/sh -c "yarn install && yarn run dev"
################################################################################## ##################################################################################
# BUILD (Does contain all files and is therefore bloated) ######################## # CODE (Does contain all code files and is pushed to DockerHub for rebranding) ###
################################################################################## ##################################################################################
FROM base as build FROM base as code
# Copy everything # copy everything, but do not build.
COPY . . COPY . .
##################################################################################
# BUILD (Does contain all files and the compilate and is therefore bloated) ######
##################################################################################
FROM code as build
# yarn install # yarn install
RUN yarn install --production=false --frozen-lockfile --non-interactive RUN yarn install --production=false --frozen-lockfile --non-interactive
# yarn build # yarn build
@ -80,16 +89,11 @@ CMD /bin/sh -c "yarn run dev"
################################################################################## ##################################################################################
FROM base as production FROM base as production
# TODO - do all copying with one COPY command to have one layer
# Copy "binary"-files from build image # Copy "binary"-files from build image
COPY --from=build ${DOCKER_WORKDIR}/.nuxt ./.nuxt COPY --from=build ${DOCKER_WORKDIR}/.nuxt ./.nuxt
COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules
COPY --from=build ${DOCKER_WORKDIR}/nuxt.config.js ./nuxt.config.js COPY --from=build ${DOCKER_WORKDIR}/nuxt.config.js ./nuxt.config.js
# Copy static files
# TODO - this should be one Folder containign all stuff needed to be copied
COPY --from=build ${DOCKER_WORKDIR}/config/ ./config/
COPY --from=build ${DOCKER_WORKDIR}/constants ./constants
COPY --from=build ${DOCKER_WORKDIR}/static ./static
COPY --from=build ${DOCKER_WORKDIR}/locales ./locales
# Copy package.json for script definitions (lock file should not be needed) # Copy package.json for script definitions (lock file should not be needed)
COPY --from=build ${DOCKER_WORKDIR}/package.json ./package.json COPY --from=build ${DOCKER_WORKDIR}/package.json ./package.json

View File

@ -1,20 +1,59 @@
FROM node:12.19.0-alpine3.10 as build ##################################################################################
LABEL Description="Maintenance page of the Social Network ocelot.social" Vendor="ocelot.social Community" Version="0.0.1" Maintainer="ocelot.social Community (devops@ocelot.social)" # BASE ###########################################################################
##################################################################################
FROM node:12.19.0-alpine3.10 as base
EXPOSE 3000 # ENVs
CMD ["yarn", "run", "start"] ## DOCKER_WORKDIR would be a classical ARG, but that is not multi layer persistent - shame
ENV DOCKER_WORKDIR="/app"
## We Cannot do `$(date -u +'%Y-%m-%dT%H:%M:%SZ')` here so we use unix timestamp=0
ARG BBUILD_DATE="1970-01-01T00:00:00.00Z"
ENV BUILD_DATE=$BBUILD_DATE
## We cannot do $(yarn run version)-${BUILD_NUMBER} here so we default to 0.0.0-0
ARG BBUILD_VERSION="0.0.0-0"
ENV BUILD_VERSION=$BBUILD_VERSION
## We cannot do `$(git rev-parse --short HEAD)` here so we default to 0000000
ARG BBUILD_COMMIT="0000000"
ENV BUILD_COMMIT=$BBUILD_COMMIT
## SET NODE_ENV
ENV NODE_ENV="production"
## App relevant Envs
ENV PORT="3000"
# Expose the app port # Labels
ARG BUILD_COMMIT LABEL org.label-schema.build-date="${BUILD_DATE}"
ENV BUILD_COMMIT=$BUILD_COMMIT LABEL org.label-schema.name="ocelot.social:backend"
ARG WORKDIR=/develop-webapp LABEL org.label-schema.description="Maintenance page of the Social Network Software ocelot.social"
RUN mkdir -p $WORKDIR LABEL org.label-schema.usage="https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/README.md"
WORKDIR $WORKDIR LABEL org.label-schema.url="https://ocelot.social"
LABEL org.label-schema.vcs-url="https://github.com/Ocelot-Social-Community/Ocelot-Social/tree/master/backend"
LABEL org.label-schema.vcs-ref="${BUILD_COMMIT}"
LABEL org.label-schema.vendor="ocelot.social Community"
LABEL org.label-schema.version="${BUILD_VERSION}"
LABEL org.label-schema.schema-version="1.0"
LABEL maintainer="devops@ocelot.social"
# See: https://github.com/nodejs/docker-node/pull/367#issuecomment-430807898 # Install Additional Software
## install: git
RUN apk --no-cache add git RUN apk --no-cache add git
# Settings
## Expose Container Port
EXPOSE ${PORT}
## Workdir
RUN mkdir -p ${DOCKER_WORKDIR}
WORKDIR ${DOCKER_WORKDIR}
CMD ["yarn", "run", "start"]
##################################################################################
# CODE (Does contain all code files and is pushed to DockerHub for rebranding) ###
##################################################################################
FROM base as code
COPY package.json yarn.lock ./ COPY package.json yarn.lock ./
# yarn install
RUN yarn install --production=false --frozen-lockfile --non-interactive RUN yarn install --production=false --frozen-lockfile --non-interactive
COPY assets assets COPY assets assets
@ -29,14 +68,24 @@ COPY constants constants
COPY nuxt.config.js nuxt.config.js COPY nuxt.config.js nuxt.config.js
COPY config/ config/ COPY config/ config/
# this is needed in rebranding
COPY maintenance/nginx maintenance/nginx
# this will also ovewrite the existing package.json # this will also ovewrite the existing package.json
COPY maintenance/source ./ COPY maintenance/source ./
##################################################################################
# BUILD ### TODO # TODO # TODO # TODO # TODO # TODO # TODO # TODO # TODO # TODO ##
##################################################################################
FROM code as build
# yarn generate
RUN yarn run generate RUN yarn run generate
##################################################################################
# PRODUCTION ### TODO # TODO # TODO # TODO # TODO # TODO # TODO # TODO # TODO ####
##################################################################################
FROM nginx:alpine as production
FROM nginx:alpine COPY --from=build ./app/dist/ /usr/share/nginx/html/
COPY --from=build ./develop-webapp/dist/ /usr/share/nginx/html/
RUN rm /etc/nginx/conf.d/default.conf RUN rm /etc/nginx/conf.d/default.conf
COPY maintenance/nginx/custom.conf /etc/nginx/conf.d/ COPY maintenance/nginx/custom.conf /etc/nginx/conf.d/

View File

@ -0,0 +1,64 @@
import { mount } from '@vue/test-utils'
import ComponentSlider from './ComponentSlider.vue'
const localVue = global.localVue
describe('ComponentSlider.vue', () => {
let wrapper
let mocks
let propsData
beforeEach(() => {
mocks = {
$t: jest.fn(),
}
propsData = {
sliderData: {
sliderIndex: 0,
sliderSelectorCallback: jest.fn().mockResolvedValue(true),
sliders: [
{
validated: true,
button: {
icon: 'smile',
callback: jest.fn().mockResolvedValue(true),
sliderCallback: jest.fn().mockResolvedValue(true),
},
},
{
validated: true,
button: {
icon: 'smile',
callback: jest.fn().mockResolvedValue(true),
sliderCallback: jest.fn().mockResolvedValue(true),
},
},
],
},
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(ComponentSlider, {
mocks,
localVue,
propsData,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.is('div')).toBe(true)
})
it('click on next Button', async () => {
await wrapper.find('.base-button[data-test="next-button"]').trigger('click')
await wrapper.vm.$nextTick()
expect(propsData.sliderData.sliderSelectorCallback).toHaveBeenCalled()
})
})
})

View File

@ -59,6 +59,8 @@
:onClick="commands.horizontal_rule" :onClick="commands.horizontal_rule"
icon="minus" icon="minus"
/> />
<menu-legend class="legend-button" />
</div> </div>
</editor-menu-bar> </editor-menu-bar>
</template> </template>
@ -66,11 +68,13 @@
<script> <script>
import { EditorMenuBar } from 'tiptap' import { EditorMenuBar } from 'tiptap'
import MenuBarButton from './MenuBarButton' import MenuBarButton from './MenuBarButton'
import MenuLegend from './MenuLegend.vue'
export default { export default {
components: { components: {
EditorMenuBar, EditorMenuBar,
MenuBarButton, MenuBarButton,
MenuLegend,
}, },
props: { props: {
editor: Object, editor: Object,
@ -78,3 +82,10 @@ export default {
}, },
} }
</script> </script>
<style lang="scss">
.legend-button {
display: inline;
position: relative;
}
</style>

View File

@ -10,7 +10,7 @@ export default {
isActive: Boolean, isActive: Boolean,
icon: String, icon: String,
label: String, label: String,
onClick: Function, onClick: { type: Function, default: () => {} },
}, },
} }
</script> </script>

View File

@ -0,0 +1,115 @@
<template>
<dropdown :placement="placement" offset="5">
<template #default="{ openMenu, closeMenu }">
<slot name="button">
<menu-bar-button
icon="question-circle"
circle
ghost
class="legend-question-button"
@mouseover.native="openMenu()"
@mouseleave.native="closeMenu()"
/>
</slot>
</template>
<template #popover="" class="legend">
<div class="legend-container">
<div class="legend-header">{{ $t(`editor.legend.legendTitle`) }}</div>
<div
:class="['legend-table', index < legendItems.length - 1 && 'legend-table-split-line']"
v-for="(item, index) in legendItems"
:key="item.name"
>
<div>
<base-button size="small" circle ghost :icon="item.iconName" class="legend-icon">
<span v-if="item.label">{{ item.label }}</span>
</base-button>
<span>{{ $t(item.name) }}</span>
</div>
<span class="tool-shortcut">{{ item.shortcut }}</span>
</div>
</div>
</template>
</dropdown>
</template>
<script>
import Dropdown from '~/components/Dropdown'
import MenuBarButton from './MenuBarButton'
export default {
components: {
Dropdown,
MenuBarButton,
},
props: {
placement: { type: String, default: 'bottom-start' },
},
data() {
return {
legendItems: [
{ iconName: 'bold', name: `editor.legend.bold`, shortcut: 'ctrl + b' },
{ iconName: 'italic', name: `editor.legend.italic`, shortcut: 'ctrl + i' },
{ iconName: 'underline', name: `editor.legend.underline`, shortcut: 'ctrl + u' },
{ iconName: 'link', name: `editor.legend.link`, shortcut: '' },
{ iconName: 'paragraph', name: `editor.legend.paragraph`, shortcut: '' },
{ label: 'H3', name: `editor.legend.heading3`, shortcut: '### + space' },
{ label: 'H4', name: `editor.legend.heading4`, shortcut: '#### + space' },
{ iconName: 'list-ul', name: `editor.legend.unorderedList`, shortcut: '* + space' },
{ iconName: 'list-ol', name: `editor.legend.orderedList`, shortcut: '1. + space' },
{ iconName: 'quote-right', name: `editor.legend.quote`, shortcut: '> + space' },
{ iconName: 'minus', name: `editor.legend.ruler`, shortcut: '---' },
],
}
},
}
</script>
<style lang="scss">
.legend-question-button {
color: $color-neutral-40;
font-size: 1.2rem !important;
}
.legend-question-button:hover {
background: none !important;
color: $color-neutral-40 !important;
}
.legend-question-button:focus {
outline: none !important;
}
.legend {
padding: 0rem;
border: 1px solid #e5e3e8;
}
.legend-container {
display: flex;
width: 18rem !important;
flex-direction: column;
}
.legend-header {
margin-bottom: 0.5em;
text-align: center;
}
.legend-table {
display: grid;
align-items: center;
grid-template-columns: 1fr 1fr;
padding: 0.2em;
}
.legend-table-split-line {
border-bottom: 0.5px solid grey;
}
.legend-table > div {
display: flex;
align-items: center;
}
.tool-shortcut {
padding-left: 2rem;
}
.legend-icon {
pointer-events: none;
margin-right: 1rem;
}
</style>

View File

@ -0,0 +1,47 @@
import { mount } from '@vue/test-utils'
import FollowButton from './FollowButton.vue'
const localVue = global.localVue
describe('FollowButton.vue', () => {
let mocks
let propsData
beforeEach(() => {
mocks = {
$t: jest.fn(),
$apollo: {
mutate: jest.fn(),
},
}
propsData = {}
})
describe('mount', () => {
let wrapper
const Wrapper = () => {
return mount(FollowButton, { mocks, propsData, localVue })
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders button and text', () => {
expect(mocks.$t).toHaveBeenCalledWith('followButton.follow')
expect(wrapper.findAll('.base-button')).toHaveLength(1)
})
it('renders button and text when followed', () => {
propsData.isFollowed = true
wrapper = Wrapper()
expect(mocks.$t).toHaveBeenCalledWith('followButton.following')
expect(wrapper.findAll('.base-button')).toHaveLength(1)
})
it.skip('toggle the button', async () => {
wrapper.find('.base-button').trigger('click') // This does not work since @click.prevent is used
expect(wrapper.vm.isFollowed).toBe(true)
})
})
})

View File

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

View File

@ -7,7 +7,7 @@
<base-card> <base-card>
<template #imageColumn> <template #imageColumn>
<a :href="links.ORGANIZATION" :title="$t('login.moreInfo', metadata)" target="_blank"> <a :href="links.ORGANIZATION" :title="$t('login.moreInfo', metadata)" target="_blank">
<img class="image" alt="Welcome" src="/img/custom/welcome.svg" /> <logo logoType="welcome" />
</a> </a>
</template> </template>
<h2 class="title">{{ $t('login.login') }}</h2> <h2 class="title">{{ $t('login.login') }}</h2>
@ -31,11 +31,7 @@
ref="password" ref="password"
:type="showPassword ? 'text' : 'password'" :type="showPassword ? 'text' : 'password'"
/> />
<span class="click-wrapper" @click="toggleShowPassword"> <show-password @show-password="toggleShowPassword" :iconName="iconName" />
<span class="icon-wrapper" :data-test="iconName">
<base-icon class="toggle-icon" :name="iconName" />
</span>
</span>
</div> </div>
<nuxt-link to="/password-reset/request"> <nuxt-link to="/password-reset/request">
{{ $t('login.forgotPassword') }} {{ $t('login.forgotPassword') }}
@ -56,13 +52,17 @@
</template> </template>
<script> <script>
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
import links from '~/constants/links.js' import links from '~/constants/links.js'
import metadata from '~/constants/metadata.js' import metadata from '~/constants/metadata.js'
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
import Logo from '~/components/Logo/Logo'
import ShowPassword from '../ShowPassword/ShowPassword.vue'
export default { export default {
components: { components: {
LocaleSwitch, LocaleSwitch,
Logo,
ShowPassword,
}, },
data() { data() {
return { return {
@ -98,9 +98,8 @@ export default {
} }
} }
}, },
toggleShowPassword(event) { toggleShowPassword() {
this.showPassword = !this.showPassword this.showPassword = !this.showPassword
event.preventDefault()
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.password.$el.children[1].children[1].focus() this.$refs.password.$el.children[1].children[1].focus()
this.$emit('focus') this.$emit('focus')
@ -114,7 +113,7 @@ export default {
.login-form { .login-form {
width: 80vw; width: 80vw;
max-width: 620px; max-width: 620px;
margin: auto; /* margin: auto; */
.base-button { .base-button {
display: block; display: block;
@ -122,9 +121,6 @@ export default {
margin-top: $space-large; margin-top: $space-large;
margin-bottom: $space-small; margin-bottom: $space-small;
} }
.image {
width: 100%;
}
} }
.password-wrapper { .password-wrapper {
@ -145,28 +141,6 @@ export default {
outline: none; outline: none;
transition: all $duration-short $ease-out; transition: all $duration-short $ease-out;
.icon-wrapper {
margin-right: 2px;
}
.click-wrapper {
padding: 8px;
align-content: center;
color: $text-color-disabled;
cursor: pointer;
}
.click-wrapper:hover {
&:focus-within {
background-color: $background-color-base;
border: $input-border-size solid $border-color-active;
.toggle-icon {
color: $text-color-base;
}
}
}
&:focus-within { &:focus-within {
background-color: $background-color-base; background-color: $background-color-base;
border: $input-border-size solid $border-color-active; border: $input-border-size solid $border-color-active;

View File

@ -0,0 +1,31 @@
import { mount } from '@vue/test-utils'
import Logo from './Logo.vue'
const localVue = global.localVue
describe('Logo.vue', () => {
let mocks, propsData, wrapper
beforeEach(() => {
mocks = {
$t: jest.fn(),
}
propsData = {
logoType: 'header',
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(Logo, { mocks, localVue, propsData })
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.findAll('.ds-logo')).toHaveLength(1)
})
})
})

View File

@ -1,24 +1,47 @@
<template> <template>
<component :is="tag" class="ds-logo" :class="[inverse && 'ds-logo-inverse']"> <component :is="tag" class="ds-logo" :class="[inverse && 'ds-logo-inverse']">
<svg-logo v-if="!inverse" class="ds-logo-svg" /> <img
<svg-logo-inverse v-else class="ds-logo-svg" /> v-if="!inverse"
class="ds-logo-svg"
:alt="metadata.APPLICATION_NAME + ' ' + logo.alt"
:src="logo.path"
:style="logoWidthStyle"
/>
<img
v-else
class="ds-logo-svg"
:alt="metadata.APPLICATION_NAME + ' ' + logo.alt"
:src="logo.path"
:style="logoWidthStyle"
/>
</component> </component>
</template> </template>
<script> <script>
import svgLogo from '~/static/img/custom/Logo-Horizontal.svg' import logos from '~/constants/logos.js'
import svgLogoInverse from '~/static/img/custom/Logo-Horizontal-Dark.svg' import metadata from '~/constants/metadata.js'
/** /**
* This component displays the brand's logo. * This component displays the brand's logo.
* @version 1.0.0 * @version 1.0.0
*/ */
export default { export default {
name: 'Logo', name: 'Logo',
components: {
svgLogo,
svgLogoInverse,
},
props: { props: {
/**
* Logo type
*/
logoType: {
type: String,
required: true,
},
/**
* Logo width
*/
logoWidth: {
type: String,
default: null,
},
/** /**
* Inverse the logo * Inverse the logo
*/ */
@ -34,6 +57,39 @@ export default {
default: 'div', default: 'div',
}, },
}, },
data() {
const logosObject = {
header: { path: logos.LOGO_HEADER_PATH, alt: 'Header', widthDefault: '130px' },
welcome: { path: logos.LOGO_WELCOME_PATH, alt: 'Welcome', widthDefault: '200px' },
signup: { path: logos.LOGO_SIGNUP_PATH, alt: 'Sign Up', widthDefault: '200px' },
logout: { path: logos.LOGO_LOGOUT_PATH, alt: 'Logging Out', widthDefault: '200px' },
passwordReset: {
path: logos.LOGO_PASSWORD_RESET_PATH,
alt: 'Reset Your Password',
widthDefault: '200px',
},
maintenance: {
path: logos.LOGO_MAINTENACE_RESET_PATH,
alt: 'Under Maintenance',
widthDefault: '75%',
},
}
return {
logo: logosObject[this.logoType],
metadata,
}
},
computed: {
logoWidthStyle() {
let width = ''
if (this.logoWidth === null) {
width = this.logo.widthDefault
} else {
width = this.logoWidth
}
return `width: ${width};`
},
},
} }
</script> </script>

View File

@ -131,6 +131,42 @@ describe('Modal.vue', () => {
}) })
}) })
}) })
describe('store/modal data contains an user', () => {
it('passes user name to report modal', () => {
state.data = {
type: 'user',
resource: {
id: 'u456',
name: 'Username',
},
}
wrapper = Wrapper()
expect(wrapper.find(DisableModal).props()).toEqual({
type: 'user',
name: 'Username',
id: 'u456',
})
})
})
describe('store/modal data contains no valid datatype', () => {
it('passes something as datatype to modal', () => {
state.data = {
type: 'something',
resource: {
id: 's456',
name: 'Username',
},
}
wrapper = Wrapper()
expect(wrapper.find(DisableModal).props()).toEqual({
type: 'something',
name: null,
id: 's456',
})
})
})
}) })
}) })
}) })

View File

@ -81,4 +81,23 @@ describe('NotificationList.vue', () => {
}) })
}) })
}) })
describe('shallowMount with no notifications', () => {
const Wrapper = () => {
return shallowMount(NotificationList, {
propsData: {},
mocks,
store,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders Notification.vue zero times', () => {
expect(wrapper.findAll(Notification)).toHaveLength(0)
})
})
}) })

View File

@ -0,0 +1,133 @@
import { config, mount } from '@vue/test-utils'
import PageFooter from './PageFooter.vue'
import linksDefault from '~/constants/links.js'
const localVue = global.localVue
config.stubs['nuxt-link'] = '<span class="nuxt-link"><slot /></span>'
describe('PageFooter.vue', () => {
let mocks
let wrapper
beforeEach(() => {
mocks = {
$t: jest.fn(),
$env: {
VERSION: 'v1.0.0',
},
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(PageFooter, { mocks, localVue })
}
describe('links.js', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('renders four links', () => {
expect(wrapper.findAll('a')).toHaveLength(4)
})
it('renders three nuxt-links', () => {
expect(wrapper.findAll('.nuxt-link')).toHaveLength(3)
})
it('renders version', () => {
expect(wrapper.find('.ds-footer').text()).toContain('v1.0.0')
})
})
describe('inflexible links', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('renders ORGANIZATION', () => {
expect(wrapper.find('a[data-test="organization-link"]').exists()).toBe(true)
})
it('renders version', () => {
expect(wrapper.find('a[data-test="version-link"]').exists()).toBe(true)
})
})
describe('flexible links not set', () => {
beforeEach(async () => {
const links = {
...linksDefault,
IMPRINT: null,
TERMS_AND_CONDITIONS: null,
CODE_OF_CONDUCT: null,
DATA_PRIVACY: null,
FAQ: null,
}
wrapper = Wrapper()
wrapper.setData({ links })
await wrapper.vm.$nextTick()
})
it('renders IMPRINT as nuxt-link', () => {
expect(wrapper.find('span[data-test="imprint-nuxt-link"]').exists()).toBe(true)
})
it('renders TERMS_AND_CONDITIONS as nuxt-link', () => {
expect(wrapper.find('span[data-test="terms-nuxt-link"]').exists()).toBe(true)
})
it('renders CODE_OF_CONDUCT as nuxt-link', () => {
expect(wrapper.find('span[data-test="code-nuxt-link"]').exists()).toBe(true)
})
it('renders DATA_PRIVACY as nuxt-link', () => {
expect(wrapper.find('span[data-test="data-nuxt-link"]').exists()).toBe(true)
})
it('renders FAQ as nuxt-link', () => {
expect(wrapper.find('span[data-test="faq-nuxt-link"]').exists()).toBe(true)
})
})
describe('flexible links set', () => {
beforeEach(async () => {
const links = {
...linksDefault,
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',
}
wrapper = Wrapper()
wrapper.setData({ links })
await wrapper.vm.$nextTick()
})
it('renders IMPRINT as "a" tag link', () => {
expect(wrapper.find(`a[href="https://ocelot.social/IMPRINT"]`).exists()).toBe(true)
})
it('renders TERMS_AND_CONDITIONS as "a" tag link', () => {
expect(wrapper.find(`a[href="https://ocelot.social/TERMS_AND_CONDITIONS"]`).exists()).toBe(
true,
)
})
it('renders CODE_OF_CONDUCT as "a" tag link', () => {
expect(wrapper.find(`a[href="https://ocelot.social/CODE_OF_CONDUCT"]`).exists()).toBe(true)
})
it('renders DATA_PRIVACY as "a" tag link', () => {
expect(wrapper.find(`a[href="https://ocelot.social/DATA_PRIVACY"]`).exists()).toBe(true)
})
it('renders FAQ as "a" tag link', () => {
expect(wrapper.find(`a[href="https://ocelot.social/FAQ"]`).exists()).toBe(true)
})
})
})
})

View File

@ -1,26 +1,67 @@
<template> <template>
<div id="footer" class="ds-footer"> <div id="footer" class="ds-footer">
<a :href="links.ORGANIZATION" target="_blank" v-html="$t('site.made')"></a> <!-- made with -->
<a :href="links.ORGANIZATION" target="_blank" data-test="organization-link">
{{ $t('site.made') }}
</a>
<span>-</span> <span>-</span>
<nuxt-link to="/imprint"> <!-- imprint -->
<nuxt-link v-if="noLinkDefined(links.IMPRINT)" to="/imprint" data-test="imprint-nuxt-link">
{{ $t('site.imprint') }} {{ $t('site.imprint') }}
</nuxt-link> </nuxt-link>
<a v-else :href="links.IMPRINT" target="_blank">
{{ $t('site.imprint') }}
</a>
<span>-</span> <span>-</span>
<nuxt-link to="/terms-and-conditions">{{ $t('site.termsAndConditions') }}</nuxt-link> <!-- 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> <span>-</span>
<nuxt-link to="/code-of-conduct">{{ $t('site.code-of-conduct') }}</nuxt-link> <!-- 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> <span>-</span>
<nuxt-link to="/data-privacy"> <!-- data privacy -->
<nuxt-link
v-if="noLinkDefined(links.DATA_PRIVACY)"
to="/data-privacy"
data-test="data-nuxt-link"
>
{{ $t('site.data-privacy') }} {{ $t('site.data-privacy') }}
</nuxt-link> </nuxt-link>
<a v-else :href="links.DATA_PRIVACY" target="_blank">
{{ $t('site.data-privacy') }}
</a>
<span>-</span> <span>-</span>
<a :href="links.FAQ" target="_blank"> <!-- 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') }} {{ $t('site.faq') }}
</a> </a>
<span>-</span> <span>-</span>
<!-- version -->
<a <a
href="https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/CHANGELOG.md" href="https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/CHANGELOG.md"
target="_blank" target="_blank"
data-test="version-link"
> >
{{ version }} {{ version }}
</a> </a>
@ -29,10 +70,16 @@
<script> <script>
import links from '~/constants/links.js' import links from '~/constants/links.js'
export default { export default {
data() { data() {
return { links, version: `v${this.$env.VERSION}` } return { links, version: `v${this.$env.VERSION}` }
}, },
methods: {
noLinkDefined(link) {
return !link || link.length === 0
},
},
} }
</script> </script>

View File

@ -126,21 +126,18 @@ describe('ChangePassword.vue', () => {
}) })
}) })
// TODO This is not a valid testcase - we have to decide if we catch the same password on clientside describe('mutation rejects', () => {
/* describe('mutation rejects', () => {
beforeEach(async () => { beforeEach(async () => {
await wrapper.find('input#oldPassword').setValue('supersecret') await wrapper.find('input#oldPassword').setValue('supersecret')
await wrapper.find('input#password').setValue('supersecret') await wrapper.find('input#password').setValue('supersecret')
await wrapper.find('input#passwordConfirmation').setValue('supersecret') await wrapper.find('input#passwordConfirmation').setValue('supersecret')
await wrapper.find('form').trigger('submit')
}) })
it('displays error message', async () => { it('displays error message', async () => {
await wrapper.find('form').trigger('submit')
await mocks.$apollo.mutate
expect(mocks.$toast.error).toHaveBeenCalledWith('Ouch!') expect(mocks.$toast.error).toHaveBeenCalledWith('Ouch!')
}) })
}) */ })
}) })
}) })
}) })

View File

@ -76,6 +76,22 @@ describe('ChangePassword ', () => {
}) })
}) })
}) })
describe('password reset not successful', () => {
beforeEach(() => {
mocks.$apollo.mutate = jest.fn().mockRejectedValue({
message: 'Ouch!',
})
wrapper = Wrapper()
wrapper.find('input#password').setValue('supersecret')
wrapper.find('input#passwordConfirmation').setValue('supersecret')
wrapper.find('form').trigger('submit')
})
it('display a toast error', () => {
expect(mocks.$toast.error).toHaveBeenCalled()
})
})
}) })
}) })
}) })

View File

@ -95,5 +95,20 @@ describe('Request', () => {
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected)
}) })
}) })
describe('backend throws an error', () => {
beforeEach(() => {
mocks.$apollo.mutate = jest.fn().mockRejectedValue({
message: 'Ouch!',
})
wrapper = Wrapper()
wrapper.find('input#email').setValue('mail@gmail.com')
wrapper.find('form').trigger('submit')
})
it('display a toast error', () => {
expect(mocks.$toast.error).toHaveBeenCalled()
})
})
}) })
}) })

View File

@ -40,24 +40,43 @@
:label="$t('settings.data.labelName')" :label="$t('settings.data.labelName')"
:placeholder="$t('settings.data.namePlaceholder')" :placeholder="$t('settings.data.namePlaceholder')"
/> />
<label for="password">
{{ $t('settings.security.change-password.label-new-password') }}
</label>
<div class="password-wrapper">
<ds-input <ds-input
id="password" id="password"
model="password" model="password"
type="password" :type="showPassword ? 'text' : 'password'"
autocomplete="off" autocomplete="off"
:label="$t('settings.security.change-password.label-new-password')" class="password-field"
ref="password"
/> />
<show-password
@show-password="toggleShowPassword('password')"
:iconName="iconNamePassword"
/>
</div>
<label for="passwordConfirmation">
{{ $t('settings.security.change-password.label-new-password-confirm') }}
</label>
<div class="password-wrapper">
<ds-input <ds-input
id="passwordConfirmation" id="passwordConfirmation"
model="passwordConfirmation" model="passwordConfirmation"
type="password" :type="showPasswordConfirm ? 'text' : 'password'"
autocomplete="off" autocomplete="off"
:label="$t('settings.security.change-password.label-new-password-confirm')" class="password-field"
ref="confirmPassword"
/> />
<show-password
@show-password="toggleShowPassword('confirmPassword')"
:iconName="iconNamePasswordConfirm"
/>
</div>
<password-strength class="password-strength" :password="formData.password" /> <password-strength class="password-strength" :password="formData.password" />
<email-display-and-verify :email="sliderData.collectedInputData.email" /> <email-display-and-verify :email="sliderData.collectedInputData.email" />
<ds-text> <ds-text>
<input <input
id="checkbox0" id="checkbox0"
@ -106,6 +125,7 @@ import EmailDisplayAndVerify from './EmailDisplayAndVerify'
import { SweetalertIcon } from 'vue-sweetalert-icons' import { SweetalertIcon } from 'vue-sweetalert-icons'
import PasswordForm from '~/components/utils/PasswordFormHelper' import PasswordForm from '~/components/utils/PasswordFormHelper'
import { SignupVerificationMutation } from '~/graphql/Registration.js' import { SignupVerificationMutation } from '~/graphql/Registration.js'
import ShowPassword from '../ShowPassword/ShowPassword.vue'
export default { export default {
name: 'RegistrationSlideCreate', name: 'RegistrationSlideCreate',
@ -113,6 +133,7 @@ export default {
PasswordStrength, PasswordStrength,
EmailDisplayAndVerify, EmailDisplayAndVerify,
SweetalertIcon, SweetalertIcon,
ShowPassword,
}, },
props: { props: {
sliderData: { type: Object, required: true }, sliderData: { type: Object, required: true },
@ -140,6 +161,8 @@ export default {
// have checkmarks available. // have checkmarks available.
termsAndConditionsConfirmed: false, termsAndConditionsConfirmed: false,
recieveCommunicationAsEmailsEtcConfirmed: false, recieveCommunicationAsEmailsEtcConfirmed: false,
showPassword: false,
showPasswordConfirm: false,
} }
}, },
mounted: function () { mounted: function () {
@ -180,6 +203,12 @@ export default {
this.recieveCommunicationAsEmailsEtcConfirmed this.recieveCommunicationAsEmailsEtcConfirmed
) )
}, },
iconNamePassword() {
return this.showPassword ? 'eye-slash' : 'eye'
},
iconNamePasswordConfirm() {
return this.showPasswordConfirm ? 'eye-slash' : 'eye'
},
}, },
watch: { watch: {
termsAndConditionsConfirmed() { termsAndConditionsConfirmed() {
@ -251,6 +280,21 @@ export default {
this.submit() this.submit()
return true return true
}, },
toggleShowPassword(e) {
if (e === 'password') {
this.showPassword = !this.showPassword
this.$nextTick(() => {
this.$refs.password.$el.children[1].children[0].focus()
this.$emit('focus')
})
} else {
this.showPasswordConfirm = !this.showPasswordConfirm
this.$nextTick(() => {
this.$refs.confirmPassword.$el.children[1].children[0].focus()
this.$emit('focus')
})
}
},
}, },
} }
</script> </script>
@ -259,4 +303,44 @@ export default {
.password-strength { .password-strength {
margin-bottom: 14px; margin-bottom: 14px;
} }
.password-wrapper {
display: flex;
width: 100%;
align-items: center;
padding: $input-padding-vertical $space-x-small;
padding-left: 0;
padding-right: 0;
height: $input-height;
margin-bottom: 10px;
margin-bottom: 16px;
color: $text-color-base;
background: $background-color-disabled;
border: $input-border-size solid $border-color-softer;
border-left: none;
border-radius: $border-radius-base;
outline: none;
transition: all $duration-short $ease-out;
&:focus-within {
background-color: $background-color-base;
border: $input-border-size solid $border-color-active;
.toggle-icon {
color: $text-color-base;
}
}
.password-field {
position: relative;
padding-top: 16px;
border: none;
border-style: none;
appearance: none;
margin-left: 0;
width: 100%;
}
}
</style> </style>

View File

@ -3,7 +3,7 @@
<base-card> <base-card>
<template #imageColumn> <template #imageColumn>
<a :href="links.ORGANIZATION" :title="$t('login.moreInfo', metadata)" target="_blank"> <a :href="links.ORGANIZATION" :title="$t('login.moreInfo', metadata)" target="_blank">
<img class="image" alt="Welcome" src="/img/custom/welcome.svg" /> <logo logoType="signup" />
</a> </a>
</template> </template>
@ -47,6 +47,7 @@ import links from '~/constants/links.js'
import metadata from '~/constants/metadata.js' import metadata from '~/constants/metadata.js'
import ComponentSlider from '~/components/ComponentSlider/ComponentSlider' import ComponentSlider from '~/components/ComponentSlider/ComponentSlider'
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch' import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
import Logo from '~/components/Logo/Logo'
import RegistrationSlideCreate from './RegistrationSlideCreate' import RegistrationSlideCreate from './RegistrationSlideCreate'
import RegistrationSlideEmail from './RegistrationSlideEmail' import RegistrationSlideEmail from './RegistrationSlideEmail'
import RegistrationSlideInvite from './RegistrationSlideInvite' import RegistrationSlideInvite from './RegistrationSlideInvite'
@ -58,6 +59,7 @@ export default {
components: { components: {
ComponentSlider, ComponentSlider,
LocaleSwitch, LocaleSwitch,
Logo,
RegistrationSlideCreate, RegistrationSlideCreate,
RegistrationSlideEmail, RegistrationSlideEmail,
RegistrationSlideInvite, RegistrationSlideInvite,

View File

@ -76,6 +76,21 @@ describe('Signup', () => {
expect(mocks.$t).toHaveBeenCalledWith(...expected) expect(mocks.$t).toHaveBeenCalledWith(...expected)
}) })
describe('mutation is rejected', () => {
beforeEach(async () => {
mocks.$apollo.mutate = jest.fn().mockRejectedValue({
message: 'Ouch!',
})
wrapper = Wrapper()
wrapper.find('input#email').setValue('mail@example.org')
await wrapper.find('form').trigger('submit')
})
it('displays error message', async () => {
expect(mocks.$toast.error).toHaveBeenCalledWith('Ouch!')
})
})
describe('after animation', () => { describe('after animation', () => {
beforeEach(jest.runAllTimers) beforeEach(jest.runAllTimers)

View File

@ -0,0 +1,57 @@
import { mount } from '@vue/test-utils'
import ShoutButton from './ShoutButton.vue'
import Vue from 'vue'
const localVue = global.localVue
describe('ShoutButton.vue', () => {
let mocks
beforeEach(() => {
mocks = {
$t: jest.fn(),
$apollo: {
mutate: jest.fn(),
},
}
})
describe('mount', () => {
let wrapper
const Wrapper = () => {
return mount(ShoutButton, { mocks, localVue })
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders button and text', () => {
expect(mocks.$t).toHaveBeenCalledWith('shoutButton.shouted')
expect(wrapper.findAll('.base-button')).toHaveLength(1)
expect(wrapper.findAll('.shout-button-text')).toHaveLength(1)
expect(wrapper.vm.shouted).toBe(false)
expect(wrapper.vm.shoutedCount).toBe(0)
})
it('toggle the button', async () => {
mocks.$apollo.mutate = jest.fn().mockResolvedValue({ data: { shout: 'WeDoShout' } })
wrapper.find('.base-button').trigger('click')
expect(wrapper.vm.shouted).toBe(true)
expect(wrapper.vm.shoutedCount).toBe(1)
await Vue.nextTick()
expect(wrapper.vm.shouted).toBe(true)
expect(wrapper.vm.shoutedCount).toBe(1)
})
it('toggle the button, but backend fails', async () => {
mocks.$apollo.mutate = jest.fn().mockRejectedValue({ message: 'Ouch!' })
await wrapper.find('.base-button').trigger('click')
expect(wrapper.vm.shouted).toBe(true)
expect(wrapper.vm.shoutedCount).toBe(1)
await Vue.nextTick()
expect(wrapper.vm.shouted).toBe(false)
expect(wrapper.vm.shoutedCount).toBe(0)
})
})
})

View File

@ -0,0 +1,33 @@
import Vue from 'vue'
import { mount } from '@vue/test-utils'
import ShowPassword from './ShowPassword.vue'
describe('ShowPassword', () => {
describe('State of show password icon', () => {
const wrapper = mount(ShowPassword, {
propsData: {
iconName: 'eye',
},
})
it('Shows eye icon by default', () => {
expect(wrapper.find('.icon-wrapper').attributes('data-test')).toEqual('eye')
})
describe('After click', () => {
it('Password wrapper emits show-password event', async () => {
wrapper.find('.click-wrapper').trigger('click')
await Vue.nextTick()
expect(wrapper.emitted()).toBeTruthy()
})
it('Shows the slash-eye icon after click', async () => {
wrapper.find('.click-wrapper').trigger('click')
wrapper.setProps({ iconName: 'eye-slash' })
await Vue.nextTick()
expect(wrapper.find('.icon-wrapper').attributes('data-test')).toEqual('eye-slash')
})
})
})
})

View File

@ -0,0 +1,44 @@
<template>
<span class="click-wrapper" @click="togglePassword">
<span class="icon-wrapper" :data-test="iconName">
<base-icon class="toggle-icon" :name="iconName" />
</span>
</span>
</template>
<script>
export default {
props: ['iconName'],
emits: ['toggle-password'],
methods: {
togglePassword(event) {
event.preventDefault()
this.$emit('show-password')
},
},
}
</script>
<style lang="scss">
.icon-wrapper {
margin-right: 2px;
}
.click-wrapper {
padding: 8px;
align-content: center;
color: $text-color-disabled;
cursor: pointer;
}
.click-wrapper:hover {
&:focus-within {
background-color: $background-color-base;
border: $input-border-size solid $border-color-active;
.toggle-icon {
color: $text-color-base;
}
}
}
</style>

View File

@ -1,5 +1,6 @@
import { storiesOf } from '@storybook/vue' import { storiesOf } from '@storybook/vue'
import helpers from '~/storybook/helpers' import helpers from '~/storybook/helpers'
import logos from '~/constants/logos.js'
import BaseCard from './BaseCard.vue' import BaseCard from './BaseCard.vue'
storiesOf('Generic/BaseCard', module) storiesOf('Generic/BaseCard', module)
@ -33,7 +34,7 @@ storiesOf('Generic/BaseCard', module)
template: ` template: `
<base-card style="width: 600px;"> <base-card style="width: 600px;">
<template #imageColumn> <template #imageColumn>
<img class="image" alt="Example image" src="/img/custom/welcome.svg" /> <img class="image" alt="Example image" src="${logos.LOGO_WELCOME_PATH}" />
</template> </template>
<h2 class="title">I am a card heading</h2> <h2 class="title">I am a card heading</h2>
<p>And I am a paragraph.</p> <p>And I am a paragraph.</p>
@ -46,7 +47,7 @@ storiesOf('Generic/BaseCard', module)
template: ` template: `
<base-card style="width: 600px;"> <base-card style="width: 600px;">
<template #imageColumn> <template #imageColumn>
<img class="image" alt="Example image" src="/img/custom/welcome.svg" /> <img class="image" alt="Example image" src="${logos.LOGO_WELCOME_PATH}" />
</template> </template>
<h2 class="title">I am a card heading</h2> <h2 class="title">I am a card heading</h2>
<p>And I am a paragraph.</p> <p>And I am a paragraph.</p>

View File

@ -34,7 +34,7 @@ describe('ReportsTable', () => {
describe('given no reports', () => { describe('given no reports', () => {
beforeEach(() => { beforeEach(() => {
propsData = { ...propsData, reports: [] } propsData = { ...propsData }
wrapper = Wrapper() wrapper = Wrapper()
}) })

View File

@ -120,5 +120,15 @@ describe('SearchableInput.vue', () => {
query: { search: 'ab' }, query: { search: 'ab' },
}) })
}) })
it('replaces irregular whitespace with a single space', async () => {
select.element.value = 'peter lustig'
select.trigger('input')
select.trigger('keyup.enter')
expect(mocks.$router.push).toHaveBeenCalledWith({
path: '/search/search-results',
query: { search: 'peter lustig' },
})
})
}) })
}) })

View File

@ -1,6 +1,13 @@
// this file is duplicated in `backend/src/config/links.js` and `webapp/constants/links.js` and replaced on rebranding
export default { export default {
ORGANIZATION: 'https://ocelot.social', ORGANIZATION: 'https://ocelot.social',
DONATE: 'https://ocelot-social.herokuapp.com/donations',
FAQ: 'https://ocelot.social',
SUPPORT: 'https://ocelot.social', SUPPORT: 'https://ocelot.social',
// on null or empty strings internal imprint is used, see 'webapp/locales/html/'
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',
} }

10
webapp/constants/logos.js Normal file
View File

@ -0,0 +1,10 @@
// this file is duplicated in `backend/src/config/logos.js` 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',
LOGO_SIGNUP_PATH: '/img/custom/logo-squared.svg',
LOGO_WELCOME_PATH: '/img/custom/logo-squared.svg',
LOGO_LOGOUT_PATH: '/img/custom/logo-squared.svg',
LOGO_PASSWORD_RESET_PATH: '/img/custom/logo-squared.svg',
LOGO_MAINTENACE_RESET_PATH: '/img/custom/logo-squared.svg',
}

View File

@ -1,8 +1,9 @@
// this file is duplicated in `backend/src/config/metadata.js` and `webapp/constants/metadata.js` and replaced on rebranding
export default { export default {
APPLICATION_NAME: 'ocelot.social', APPLICATION_NAME: 'ocelot.social',
APPLICATION_SHORT_NAME: 'ocelot', APPLICATION_SHORT_NAME: 'ocelot.social',
APPLICATION_DESCRIPTION: 'ocelot.social Community Network', APPLICATION_DESCRIPTION: 'ocelot.social Community Network',
COOKIE_NAME: 'ocelot-social-token',
ORGANIZATION_NAME: 'ocelot.social Community', ORGANIZATION_NAME: 'ocelot.social Community',
ORGANIZATION_JURISDICTION: 'City of Angels', ORGANIZATION_JURISDICTION: 'City of Angels',
COOKIE_NAME: 'ocelot-social-token',
} }

View File

@ -0,0 +1,34 @@
import { config, shallowMount } from '@vue/test-utils'
import Basic from './basic.vue'
const localVue = global.localVue
config.stubs.nuxt = '<span><slot /></span>'
describe('basic.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: jest.fn(),
}
})
describe('shallow mount', () => {
const Wrapper = () => {
return shallowMount(Basic, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.is('.layout-blank')).toBe(true)
})
})
})

View File

@ -6,7 +6,7 @@
<ds-flex-item width="5.5%" /> <ds-flex-item width="5.5%" />
<ds-flex-item style="flex-grow: 1" width="20%"> <ds-flex-item style="flex-grow: 1" width="20%">
<a @click="redirectToRoot"> <a @click="redirectToRoot">
<logo /> <logo logoType="header" />
</a> </a>
</ds-flex-item> </ds-flex-item>
<ds-flex-item width="20%" style="flex-grow: 0"> <ds-flex-item width="20%" style="flex-grow: 0">

View File

@ -0,0 +1,34 @@
import { config, shallowMount } from '@vue/test-utils'
import Blank from './blank.vue'
const localVue = global.localVue
config.stubs.nuxt = '<span><slot /></span>'
describe('blank.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: jest.fn(),
}
})
describe('shallow mount', () => {
const Wrapper = () => {
return shallowMount(Blank, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.is('.layout-blank')).toBe(true)
})
})
})

View File

@ -0,0 +1,52 @@
import Vuex from 'vuex'
import { config, shallowMount } from '@vue/test-utils'
import Default from './default.vue'
const localVue = global.localVue
localVue.directive('scrollTo', jest.fn())
config.stubs.nuxt = '<span><slot /></span>'
config.stubs['client-only'] = '<span><slot /></span>'
config.stubs['nuxt-link'] = '<span><slot /></span>'
describe('default.vue', () => {
let wrapper
let mocks
let store
beforeEach(() => {
mocks = {
$route: {
matched: [{ name: 'index' }],
},
$scrollTo: jest.fn(),
$t: jest.fn(),
$env: {
INVITE_REGISTRATION: true,
},
}
store = new Vuex.Store({
getters: {
'auth/isLoggedIn': () => true,
},
})
})
describe('shallow mount', () => {
const Wrapper = () => {
return shallowMount(Default, {
store,
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.is('.layout-default')).toBe(true)
})
})
})

View File

@ -6,7 +6,7 @@
<ds-flex class="main-navigation-flex"> <ds-flex class="main-navigation-flex">
<ds-flex-item :width="{ base: '142px' }"> <ds-flex-item :width="{ base: '142px' }">
<nuxt-link :to="{ name: 'index' }" v-scroll-to="'.main-navigation'"> <nuxt-link :to="{ name: 'index' }" v-scroll-to="'.main-navigation'">
<logo /> <logo logoType="header" />
</nuxt-link> </nuxt-link>
</ds-flex-item> </ds-flex-item>
<ds-flex-item <ds-flex-item

View File

@ -313,6 +313,20 @@
"addLetter": "Tippe einen Buchstaben", "addLetter": "Tippe einen Buchstaben",
"noHashtagsFound": "Keine Hashtags gefunden" "noHashtagsFound": "Keine Hashtags gefunden"
}, },
"legend": {
"bold": "Fett",
"heading3": "Überschrift 3",
"heading4": "Überschrift 4",
"italic": "Kursiv",
"legendTitle": "Tastaturkürzel und Markdown-Code",
"link": "Verlinkung",
"orderedList": "Geordnete Liste",
"paragraph": "Absatz",
"quote": "Zitat",
"ruler": "Linie",
"underline": "Unterstrichen",
"unorderedList": "Ungeordnete Liste"
},
"mention": { "mention": {
"noUsersFound": "Keine Benutzer gefunden" "noUsersFound": "Keine Benutzer gefunden"
}, },
@ -771,7 +785,7 @@
"faq": "FAQ", "faq": "FAQ",
"germany": "Deutschland", "germany": "Deutschland",
"imprint": "Impressum", "imprint": "Impressum",
"made": "Mit &#10084; gemacht", "made": "Mit ❤️ gemacht",
"register": "Registernummer", "register": "Registernummer",
"responsible": "Verantwortlich für Inhalte dieser Seite (§ 55 Abs. 2 RStV)", "responsible": "Verantwortlich für Inhalte dieser Seite (§ 55 Abs. 2 RStV)",
"taxident": "Umsatzsteuer-Identifikationsnummer gemäß § 27 a Umsatzsteuergesetz (Deutschland)", "taxident": "Umsatzsteuer-Identifikationsnummer gemäß § 27 a Umsatzsteuergesetz (Deutschland)",

View File

@ -313,6 +313,20 @@
"addLetter": "Type a letter", "addLetter": "Type a letter",
"noHashtagsFound": "No hashtags found" "noHashtagsFound": "No hashtags found"
}, },
"legend": {
"bold": "Bold",
"heading3": "Heading 3",
"heading4": "Heading 4",
"italic": "Italic",
"legendTitle": "Keyboard shortcuts and markdown code",
"link": "Link",
"orderedList": "Ordered list",
"paragraph": "Paragraph",
"quote": "Quote",
"ruler": "Ruler",
"underline": "Underline",
"unorderedList": "Unordered list"
},
"mention": { "mention": {
"noUsersFound": "No users found" "noUsersFound": "No users found"
}, },
@ -771,7 +785,7 @@
"faq": "FAQ", "faq": "FAQ",
"germany": "Germany", "germany": "Germany",
"imprint": "Imprint", "imprint": "Imprint",
"made": "Made with &#10084;", "made": "Made with ❤️",
"register": "Registry number", "register": "Registry number",
"responsible": "responsible for contents of this page (§ 55 Abs. 2 RStV)", "responsible": "responsible for contents of this page (§ 55 Abs. 2 RStV)",
"taxident": "USt-ID. according to §27a of the German Sales Tax Law:", "taxident": "USt-ID. according to §27a of the German Sales Tax Law:",

View File

@ -694,7 +694,7 @@
"faq": "Preguntas más frecuentes", "faq": "Preguntas más frecuentes",
"germany": "Alemania", "germany": "Alemania",
"imprint": "Pie de imprenta", "imprint": "Pie de imprenta",
"made": "Hecho con &#10084;", "made": "Hecho con ❤️",
"register": "Número de registro", "register": "Número de registro",
"responsible": "Responsable según § 55 Abs. 2 RStV (Alemania)", "responsible": "Responsable según § 55 Abs. 2 RStV (Alemania)",
"taxident": "Número de identificación del impuesto sobre el valor añadido según el § 27 a de la Ley del Impuesto sobre el Valor Añadido (Alemania)", "taxident": "Número de identificación del impuesto sobre el valor añadido según el § 27 a de la Ley del Impuesto sobre el Valor Añadido (Alemania)",

View File

@ -662,7 +662,7 @@
"faq": "FAQ", "faq": "FAQ",
"germany": "Allemagne", "germany": "Allemagne",
"imprint": "Mentions légales", "imprint": "Mentions légales",
"made": "Fabriqué avec &#10084;", "made": "Fabriqué avec ❤️",
"register": "Numéro de registre", "register": "Numéro de registre",
"responsible": "Responsable selon § 55 Abs. 2 RStV (Allemagne)", "responsible": "Responsable selon § 55 Abs. 2 RStV (Allemagne)",
"taxident": "Numéro d'identification à la taxe sur la valeur ajoutée selon § 27 a de la loi sur la taxe sur la valeur ajoutée (Allemagne)", "taxident": "Numéro d'identification à la taxe sur la valeur ajoutée selon § 27 a de la loi sur la taxe sur la valeur ajoutée (Allemagne)",

View File

@ -1 +1,3 @@
<!-- this file is replaced on rebranding -->
<p>Ich bin der Inhalt vom Verhaltenskodex</p> <p>Ich bin der Inhalt vom Verhaltenskodex</p>

View File

@ -1 +1,3 @@
<!-- this file is replaced on rebranding -->
<p>Das hier wäre der Inhalt der Datenschutzbestimmungen</p> <p>Das hier wäre der Inhalt der Datenschutzbestimmungen</p>

View File

@ -0,0 +1,3 @@
<!-- this file is replaced on rebranding -->
<p>Hier stehen die FAQs</p>

View File

@ -1 +1,3 @@
<!-- this file is replaced on rebranding -->
<p>Ich bin das Impressum</p> <p>Ich bin das Impressum</p>

View File

@ -1,11 +1,13 @@
import termsAndConditions from './terms-and-conditions.html' import termsAndConditions from './terms-and-conditions.html'
import codeOfConduct from './code-of-conduct.html' import codeOfConduct from './code-of-conduct.html'
import dataPrivacy from './data-privacy.html' import dataPrivacy from './data-privacy.html'
import faq from './faq.html'
import imprint from './imprint.html' import imprint from './imprint.html'
export default { export default {
termsAndConditions, termsAndConditions,
codeOfConduct, codeOfConduct,
dataPrivacy, dataPrivacy,
faq,
imprint, imprint,
} }

View File

@ -1 +1,3 @@
<!-- this file is replaced on rebranding -->
<p>Ich bin der Inhalt der Seite "Nutzungsbedingungen"</p> <p>Ich bin der Inhalt der Seite "Nutzungsbedingungen"</p>

View File

@ -1 +1,3 @@
<!-- this file is replaced on rebranding -->
<p>I am the content of the code of conduct</p> <p>I am the content of the code of conduct</p>

View File

@ -1 +1,3 @@
<!-- this file is replaced on rebranding -->
<p>This would be our data privacy section</p> <p>This would be our data privacy section</p>

View File

@ -0,0 +1,3 @@
<!-- this file is replaced on rebranding -->
<p>Here are the FAQs</p>

View File

@ -1 +1,3 @@
<!-- this file is replaced on rebranding -->
<p>I am the imprint</p> <p>I am the imprint</p>

View File

@ -1,11 +1,13 @@
import termsAndConditions from './terms-and-conditions.html' import termsAndConditions from './terms-and-conditions.html'
import codeOfConduct from './code-of-conduct.html' import codeOfConduct from './code-of-conduct.html'
import dataPrivacy from './data-privacy.html' import dataPrivacy from './data-privacy.html'
import faq from './faq.html'
import imprint from './imprint.html' import imprint from './imprint.html'
export default { export default {
termsAndConditions, termsAndConditions,
codeOfConduct, codeOfConduct,
dataPrivacy, dataPrivacy,
faq,
imprint, imprint,
} }

View File

@ -1 +1,3 @@
<!-- this file is replaced on rebranding -->
<p>I am the content of the page "terms and conditions"<p> <p>I am the content of the page "terms and conditions"<p>

View File

@ -612,7 +612,7 @@
"faq": null, "faq": null,
"germany": "Germania", "germany": "Germania",
"imprint": "Impressum", "imprint": "Impressum",
"made": "Con &#10084; fatto", "made": "Con ❤️ fatto",
"register": "numero di registro", "register": "numero di registro",
"responsible": "Responsabile ai sensi del § 55 Abs. 2 RStV (Germania)", "responsible": "Responsabile ai sensi del § 55 Abs. 2 RStV (Germania)",
"taxident": "Numero di identificazione dell'imposta sul valore aggiunto ai sensi del § 27 a Legge sull'imposta sul valore aggiunto (Germania)", "taxident": "Numero di identificazione dell'imposta sul valore aggiunto ai sensi del § 27 a Legge sull'imposta sul valore aggiunto (Germania)",

View File

@ -165,7 +165,7 @@
"director": "Directeur", "director": "Directeur",
"germany": "Duitsland", "germany": "Duitsland",
"imprint": "Afdruk", "imprint": "Afdruk",
"made": "Met &#10084; gemaakt", "made": "Met ❤️ gemaakt",
"register": "inschrijfnummer", "register": "inschrijfnummer",
"responsible": "Verantwoordelijk volgens § 55 Abs. 2 RStV (Duitsland).", "responsible": "Verantwoordelijk volgens § 55 Abs. 2 RStV (Duitsland).",
"taxident": "Identificatienummer voor de belasting over de toegevoegde waarde overeenkomstig § 27 a Wet op de belasting over de toegevoegde waarde (Duitsland).", "taxident": "Identificatienummer voor de belasting over de toegevoegde waarde overeenkomstig § 27 a Wet op de belasting over de toegevoegde waarde (Duitsland).",

View File

@ -350,7 +350,7 @@
"director": "Dyrektor zarządzający", "director": "Dyrektor zarządzający",
"germany": "Niemcy", "germany": "Niemcy",
"imprint": "Nadruk", "imprint": "Nadruk",
"made": "Z &#10084; zrobiony", "made": "Z ❤️ zrobiony",
"register": "numer rejestracyjny", "register": "numer rejestracyjny",
"responsible": "Odpowiedzialny zgodnie z § 55 Abs. 2 RStV (Niemcy)", "responsible": "Odpowiedzialny zgodnie z § 55 Abs. 2 RStV (Niemcy)",
"taxident": "Numer identyfikacyjny podatku od wartości dodanej zgodnie z § 27 a Ustawa o podatku od wartości dodanej (Niemcy)", "taxident": "Numer identyfikacyjny podatku od wartości dodanej zgodnie z § 27 a Ustawa o podatku od wartości dodanej (Niemcy)",

View File

@ -647,7 +647,7 @@
"faq": "FAQ", "faq": "FAQ",
"germany": "Alemanha", "germany": "Alemanha",
"imprint": "Impressão", "imprint": "Impressão",
"made": "Feito com &#10084;", "made": "Feito com ❤️",
"register": "número de registo", "register": "número de registo",
"responsible": "Responsável segundo § 55 Abs. 2 RStV (Alemanha) ", "responsible": "Responsável segundo § 55 Abs. 2 RStV (Alemanha) ",
"taxident": "Número de identificação do imposto sobre o valor acrescentado de acordo com o § 27 da Lei do Imposto sobre o Valor Acrescentado (Alemanha)", "taxident": "Número de identificação do imposto sobre o valor acrescentado de acordo com o § 27 da Lei do Imposto sobre o Valor Acrescentado (Alemanha)",

View File

@ -260,6 +260,20 @@
"addLetter": "Введите букву", "addLetter": "Введите букву",
"noHashtagsFound": "Хэштеги не найдены" "noHashtagsFound": "Хэштеги не найдены"
}, },
"legend": {
"bold": "Полужирный",
"heading3": "Заголовок 3",
"heading4": "Заголовок 4",
"italic": "Курсив",
"legendTitle": "Клавиатурные сокращения и код разметки",
"link": "Ссылка",
"orderedList": "Нумерованный список",
"paragraph": "Параграф",
"quote": "Кавычки",
"ruler": "Горизонтальная линия",
"underline": "Подчеркнутый",
"unorderedList": "Маркированный список"
},
"mention": { "mention": {
"noUsersFound": "Пользователи не найдены" "noUsersFound": "Пользователи не найдены"
}, },
@ -694,7 +708,7 @@
"faq": "ЧаВо (FAQ)", "faq": "ЧаВо (FAQ)",
"germany": "Германия", "germany": "Германия",
"imprint": "Импрессум", "imprint": "Импрессум",
"made": "Сделано с &#10084;", "made": "Сделано с ❤️",
"register": "Регистрационный номер", "register": "Регистрационный номер",
"responsible": "ответственный за содержание этой страницы (§ 55 Abs. 2 RStV)", "responsible": "ответственный за содержание этой страницы (§ 55 Abs. 2 RStV)",
"taxident": "UST-ID. в соответствии с §27a Закона о налоге с продаж Германии:", "taxident": "UST-ID. в соответствии с §27a Закона о налоге с продаж Германии:",

View File

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

View File

@ -9,11 +9,7 @@
<ds-flex-item :width="{ base: '100%', sm: 1, md: 1 }"> <ds-flex-item :width="{ base: '100%', sm: 1, md: 1 }">
<ds-space> <ds-space>
<a :href="links.ORGANIZATION" :title="$t('login.moreInfo', metadata)" target="_blank"> <a :href="links.ORGANIZATION" :title="$t('login.moreInfo', metadata)" target="_blank">
<img <img class="image" alt="Under maintenance" src="/img/custom/logo-squared.svg" />
class="image"
alt="Under maintenance"
src="/img/custom/under-maintenance.svg"
/>
</a> </a>
</ds-space> </ds-space>
</ds-flex-item> </ds-flex-item>

4806
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", "name": "ocelot-social-webapp",
"version": "1.0.2", "version": "1.0.4",
"description": "ocelot.social Frontend", "description": "ocelot.social Frontend",
"repository": "https://github.com/Ocelot-Social-Community/Ocelot-Social", "repository": "https://github.com/Ocelot-Social-Community/Ocelot-Social",
"author": "ocelot.social Community", "author": "ocelot.social Community",
@ -24,9 +24,17 @@
"verbose": true, "verbose": true,
"collectCoverageFrom": [ "collectCoverageFrom": [
"**/*.{js,vue}", "**/*.{js,vue}",
"!**/?(*.)+(spec|test|story).js?(x)",
"!**/node_modules/**", "!**/node_modules/**",
"!**/.nuxt/**", "!**/.nuxt/**",
"!**/?(*.)+(spec|test).js?(x)" "!**/storybook/**",
"!**/coverage/**",
"!**/config/**",
"!**/maintenance/**",
"!**/plugins/**",
"!**/.eslintrc.js",
"!**/.prettierrc.js",
"!**/nuxt.config.js"
], ],
"coverageReporters": [ "coverageReporters": [
"lcov" "lcov"
@ -41,10 +49,10 @@
"vue" "vue"
], ],
"moduleNameMapper": { "moduleNameMapper": {
"^@/(.*)$": "<rootDir>/src/$1", "\\.(svg)$": "<rootDir>/test/fileMock.js",
"^~/(.*)$": "<rootDir>/$1",
"\\.(css|less)$": "identity-obj-proxy", "\\.(css|less)$": "identity-obj-proxy",
"\\.(svg)$": "<rootDir>/test/fileMock.js" "^@/(.*)$": "<rootDir>/src/$1",
"^~/(.*)$": "<rootDir>/$1"
}, },
"setupFiles": [ "setupFiles": [
"<rootDir>/test/registerContext.js", "<rootDir>/test/registerContext.js",
@ -65,12 +73,12 @@
"accounting": "~0.4.1", "accounting": "~0.4.1",
"apollo-cache-inmemory": "~1.6.5", "apollo-cache-inmemory": "~1.6.5",
"apollo-client": "~2.6.8", "apollo-client": "~2.6.8",
"cookie-universal-nuxt": "~2.1.3", "cookie-universal-nuxt": "~2.1.5",
"cropperjs": "^1.5.5", "cropperjs": "^1.5.5",
"cross-env": "~7.0.2", "cross-env": "~7.0.2",
"date-fns": "2.12.0", "date-fns": "2.12.0",
"express": "~4.17.1", "express": "~4.17.1",
"graphql": "~14.6.0", "graphql": "~14.7.0",
"intersection-observer": "^0.12.0", "intersection-observer": "^0.12.0",
"jsonwebtoken": "~8.5.1", "jsonwebtoken": "~8.5.1",
"linkify-it": "~2.2.0", "linkify-it": "~2.2.0",
@ -125,7 +133,7 @@
"eslint-plugin-jest": "~24.1.3", "eslint-plugin-jest": "~24.1.3",
"eslint-plugin-node": "~11.1.0", "eslint-plugin-node": "~11.1.0",
"eslint-plugin-prettier": "~3.1.4", "eslint-plugin-prettier": "~3.1.4",
"eslint-plugin-promise": "~4.2.1", "eslint-plugin-promise": "~4.3.1",
"eslint-plugin-standard": "~5.0.0", "eslint-plugin-standard": "~5.0.0",
"eslint-plugin-vue": "~6.2.2", "eslint-plugin-vue": "~6.2.2",
"faker": "^5.1.0", "faker": "^5.1.0",

View File

@ -0,0 +1,34 @@
import { config, mount } from '@vue/test-utils'
import admin from './admin.vue'
config.stubs['nuxt-child'] = '<span><slot /></span>'
const localVue = global.localVue
describe('admin.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: jest.fn(),
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(admin, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.is('div')).toBe(true)
})
})
})

View File

@ -0,0 +1,32 @@
import { mount } from '@vue/test-utils'
import Categories from './categories.vue'
const localVue = global.localVue
describe('categories.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: jest.fn(),
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(Categories, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.is('.base-card')).toBe(true)
})
})
})

View File

@ -0,0 +1,32 @@
import { mount } from '@vue/test-utils'
import Donations from './donations.vue'
const localVue = global.localVue
describe('donations.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: jest.fn(),
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(Donations, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.is('.base-card')).toBe(true)
})
})
})

View File

@ -0,0 +1,32 @@
import { mount } from '@vue/test-utils'
import Hashtags from './hashtags.vue'
const localVue = global.localVue
describe('hashtags.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: jest.fn(),
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(Hashtags, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.is('.base-card')).toBe(true)
})
})
})

View File

@ -0,0 +1,35 @@
import { mount } from '@vue/test-utils'
import Invite from './invite.vue'
const localVue = global.localVue
describe('invite.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: jest.fn(),
$apollo: {
loading: false,
},
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(Invite, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.is('.ds-section')).toBe(true)
})
})
})

View File

@ -0,0 +1,35 @@
import { mount } from '@vue/test-utils'
import Notifications from './notifications.vue'
const localVue = global.localVue
describe('notifications.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: jest.fn(),
$apollo: {
loading: false,
},
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(Notifications, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.is('.base-card')).toBe(true)
})
})
})

View File

@ -0,0 +1,35 @@
import { mount } from '@vue/test-utils'
import Organizations from './organizations.vue'
const localVue = global.localVue
describe('organizations.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: jest.fn(),
$apollo: {
loading: false,
},
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(Organizations, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.is('.base-card')).toBe(true)
})
})
})

View File

@ -0,0 +1,35 @@
import { mount } from '@vue/test-utils'
import Pages from './pages.vue'
const localVue = global.localVue
describe('pages.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: jest.fn(),
$apollo: {
loading: false,
},
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(Pages, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.is('.base-card')).toBe(true)
})
})
})

View File

@ -0,0 +1,35 @@
import { mount } from '@vue/test-utils'
import Settings from './settings.vue'
const localVue = global.localVue
describe('settings.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: jest.fn(),
$apollo: {
loading: false,
},
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(Settings, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.is('.base-card')).toBe(true)
})
})
})

View File

@ -0,0 +1,38 @@
import { mount } from '@vue/test-utils'
import CodeOfConduct from './code-of-conduct.vue'
import VueMeta from 'vue-meta'
const localVue = global.localVue
localVue.use(VueMeta, { keyName: 'head' })
describe('code-of-conduct.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: (t) => t,
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(CodeOfConduct, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.is('div')).toBe(true)
})
it('has correct <head> content', () => {
expect(wrapper.vm.$metaInfo.title).toBe('site.code-of-conduct')
})
})
})

View File

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<ds-space> <ds-space margin="small">
<ds-heading tag="h2">{{ $t('site.code-of-conduct') }}</ds-heading> <ds-heading tag="h2">{{ $t('site.code-of-conduct') }}</ds-heading>
</ds-space> </ds-space>
<ds-container> <ds-container>

View File

@ -0,0 +1,38 @@
import { mount } from '@vue/test-utils'
import DataPrivacy from './data-privacy.vue'
import VueMeta from 'vue-meta'
const localVue = global.localVue
localVue.use(VueMeta, { keyName: 'head' })
describe('data-privacy.vue', () => {
let wrapper
let mocks
beforeEach(() => {
mocks = {
$t: (t) => t,
}
})
describe('mount', () => {
const Wrapper = () => {
return mount(DataPrivacy, {
mocks,
localVue,
})
}
beforeEach(() => {
wrapper = Wrapper()
})
it('renders', () => {
expect(wrapper.is('div')).toBe(true)
})
it('has correct <head> content', () => {
expect(wrapper.vm.$metaInfo.title).toBe('site.data-privacy')
})
})
})

View File

@ -1,9 +1,8 @@
<template> <template>
<div> <div>
<ds-space> <ds-space margin="small">
<ds-heading tag="h2">{{ $t('site.data-privacy') }}</ds-heading> <ds-heading tag="h2">{{ $t('site.data-privacy') }}</ds-heading>
</ds-space> </ds-space>
<ds-container> <ds-container>
<div v-html="$t('html.dataPrivacy')" /> <div v-html="$t('html.dataPrivacy')" />
</ds-container> </ds-container>

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