Merge branch 'master' into 6640-devops-add-github-action-to-create-a-formatted-changelog

This commit is contained in:
mahula 2023-12-11 15:58:44 +01:00 committed by GitHub
commit a077f125cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
91 changed files with 23480 additions and 6799 deletions

View File

@ -2,6 +2,7 @@ backend: &backend
- '.github/workflows/test-backend.yml'
- 'backend/**/*'
- 'neo4j/**/*'
- 'package.json'
docker: &docker
- 'docker-compose.*'
@ -9,3 +10,7 @@ docker: &docker
webapp: &webapp
- '.github/workflows/test-webapp.yml'
- 'webapp/**/*'
- 'package.json'
markdown-files: &markdown-files
- '**/*.md'

View File

@ -0,0 +1,41 @@
name: ocelot.social check documentation
on: push
jobs:
files-changed:
name: Detect File Changes - Markdown files
runs-on: ubuntu-latest
outputs:
markdown-files: ${{ steps.changes.outputs.markdown-files }}
steps:
- name: Checkout code
uses: actions/checkout@master
- name: Check for markdown file changes
uses: dorny/paths-filter@v2.11.1
id: changes
with:
token: ${{ github.token }}
filters: .github/file-filters.yml
list-files: shell
check-markdown-links:
name: Check Markdown links
if: needs.files-changed.outputs.markdown-files == 'true'
needs: files-changed
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@master
- name: Remove old documentation files
run: rm -rf ./deployment/src/old/ # workaround until https://github.com/gaurav-nelson/github-action-markdown-link-check/pull/183 has been done
- name: Check Markdown Links
uses: gaurav-nelson/github-action-markdown-link-check@master
with:
use-quiet-mode: 'yes'
use-verbose-mode: 'no'
check-modified-files-only: 'no'
config-file: '.github/workflows/mlc_config.json'
base-branch: 'master'
folder-path: '.'

View File

@ -22,7 +22,7 @@ jobs:
continue-on-error: true
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Cleanup
run: |

12
.github/workflows/mlc_config.json vendored Normal file
View File

@ -0,0 +1,12 @@
{
"timeout": "20s",
"retryOn429": true,
"retryCount": 2,
"fallbackRetryDelay": "30s",
"aliveStatusCodes": [200, 206, 303, 403],
"ignorePatterns": [
{
"pattern": "^(https:\/\/github.com\/Ocelot-Social-Community\/Ocelot-Social\/pull\/|http:\/\/localhost)"
}
]
}

View File

@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup env
run: |
echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
@ -47,7 +47,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup env
run: |
echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
@ -96,7 +96,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup env
run: |
echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
@ -145,7 +145,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup env
run: |
echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
@ -243,7 +243,7 @@ jobs:
needs: [upload_to_dockerhub]
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch full History for changelog
- name: Setup env
@ -311,7 +311,7 @@ jobs:
needs: [github_tag]
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch full History for changelog
- name: Setup env

View File

@ -11,7 +11,7 @@ jobs:
backend: ${{ steps.changes.outputs.backend }}
docker: ${{ steps.changes.outputs.docker }}
steps:
- uses: actions/checkout@v3.3.0
- uses: actions/checkout@v4
- name: Check for backend file changes
uses: dorny/paths-filter@v2.11.1
@ -28,7 +28,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Neo4J | Build 'community' image
run: |
@ -37,7 +37,7 @@ jobs:
- name: Cache docker images
id: cache-neo4j
uses: actions/cache/save@v3.3.1
uses: actions/cache/save@v3.3.2
with:
path: /tmp/neo4j.tar
key: ${{ github.run_id }}-backend-neo4j-cache
@ -49,7 +49,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: backend | Build 'test' image
run: |
@ -58,7 +58,7 @@ jobs:
- name: Cache docker images
id: cache-backend
uses: actions/cache/save@v3.3.1
uses: actions/cache/save@v3.3.2
with:
path: /tmp/backend.tar
key: ${{ github.run_id }}-backend-cache
@ -70,7 +70,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: backend | Lint
run: cd backend && yarn && yarn run lint
@ -84,17 +84,17 @@ jobs:
checks: write
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Restore Neo4J cache
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
with:
path: /tmp/neo4j.tar
key: ${{ github.run_id }}-backend-neo4j-cache
fail-on-cache-miss: true
- name: Restore Backend cache
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
with:
path: /tmp/backend.tar
key: ${{ github.run_id }}-backend-cache
@ -127,6 +127,7 @@ jobs:
if: ${{ needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.docker == 'true' }}
needs: [files-changed, unit_test_backend]
runs-on: ubuntu-latest
permissions: write-all
continue-on-error: true
steps:
- name: Delete cache

View File

@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Copy env files
run: |
@ -36,7 +36,7 @@ jobs:
- name: Cache docker images
id: cache
uses: actions/cache/save@v3.3.1
uses: actions/cache/save@v3.3.2
with:
path: |
/opt/cucumber-json-formatter
@ -58,7 +58,7 @@ jobs:
job: [1, 2, 3, 4, 5, 6, 7, 8]
steps:
- name: Restore cache
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
id: cache
with:
path: |
@ -101,6 +101,7 @@ jobs:
name: Cleanup
needs: [docker_preparation, fullstack_tests]
runs-on: ubuntu-latest
permissions: write-all
continue-on-error: true
steps:
- name: Delete cache

View File

@ -11,7 +11,7 @@ jobs:
docker: ${{ steps.changes.outputs.docker }}
webapp: ${{ steps.changes.outputs.webapp }}
steps:
- uses: actions/checkout@v3.3.0
- uses: actions/checkout@v4
- name: Check for frontend file changes
uses: dorny/paths-filter@v2.11.1
@ -28,7 +28,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Check translation files
run: |
@ -42,7 +42,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Webapp | Build 'test' image
run: |
@ -50,7 +50,7 @@ jobs:
docker save "ocelotsocialnetwork/webapp:test" > /tmp/webapp.tar
- name: Cache docker image
uses: actions/cache/save@v3.3.1
uses: actions/cache/save@v3.3.2
with:
path: /tmp/webapp.tar
key: ${{ github.run_id }}-webapp-cache
@ -62,7 +62,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: webapp | Lint
run: cd webapp && yarn && yarn run lint
@ -76,10 +76,10 @@ jobs:
checks: write
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Restore webapp cache
uses: actions/cache/restore@v3.3.1
uses: actions/cache/restore@v3.3.2
with:
path: /tmp/webapp.tar
key: ${{ github.run_id }}-webapp-cache
@ -103,6 +103,7 @@ jobs:
if: ${{ needs.files-changed.outputs.docker == 'true' || needs.files-changed.outputs.webapp == 'true' }}
needs: [files-changed, unit_test_webapp]
runs-on: ubuntu-latest
permissions: write-all
continue-on-error: true
steps:
- name: Delete cache

2
.nvmrc
View File

@ -1 +1 @@
v19.4.0
v20.2.0

11
.vuepress/config.js Normal file
View File

@ -0,0 +1,11 @@
import { defineUserConfig } from 'vuepress'
import meta from './config/meta'
import theme from './config/theme'
import plugins from './config/plugins'
export default defineUserConfig({
pagePatterns: ['**/*.md', '!.vuepress', '!node_modules', '!backend/node_modules', '!webapp/node_modules', '!deployment/src/old'],
...meta,
theme,
plugins,
})

8
.vuepress/config/meta.js Normal file
View File

@ -0,0 +1,8 @@
export default {
base: '/',
title: 'Ocelot.Social Documentation',
description: 'Ocelot.Social Documentation',
head: [
['meta', {name: 'viewport', content: 'width=device-width,initial-scale=1'}],
],
}

View File

@ -0,0 +1,18 @@
import { searchProPlugin } from 'vuepress-plugin-search-pro'
export default [
searchProPlugin({
indexContent: true,
autoSuggestions: true,
customFields: [
{
getter: (page) => page.frontmatter.category,
formatter: "Category: $content",
},
{
getter: (page) => page.frontmatter.tag,
formatter: "Tag: $content",
},
],
})
]

82
.vuepress/config/theme.js Normal file
View File

@ -0,0 +1,82 @@
import path from 'path'
import fs from 'fs'
import { hopeTheme } from 'vuepress-theme-hope'
export default hopeTheme({
favicon: 'favicon.ico',
logo: '/logo.svg',
docsRepo: 'https://github.com/Ocelot-Social-Community/Ocelot-Social',
docsBranch: 'master',
docsDir: '.',
editLink: true,
lastUpdated: false,
contributors: false,
print: false,
pure: true,
displayFooter: true,
footer: 'CC BY busFaktor() e.V. & Authors',
sidebar: generateSidebar('../../SUMMARY.md'),
navbar: [
{ text: 'Home', link: '/' },
{
text: 'Github',
link: 'https://github.com/Ocelot-Social-Community/Ocelot-Social'
},
],
plugins: {
mdEnhance: {
tabs: true,
imgSize: true
}
}
})
function generateSidebar(summaryFileName) {
const summaryFile = path.resolve(__dirname, summaryFileName)
try {
return getSummaryData(summaryFile)
} catch (err) {
console.error(`Error generating sidebar from file ${summaryFileName}:`, err)
process.exit(1)
}
}
function getSummaryData(file) {
const lines = fs.readFileSync(file, 'utf8').split('\n')
const sidebarStructure = []
let currentParent = null
lines.forEach((line, i) => {
const level = line.search(/\S|$/) / 2
const match = line.match(/^\s*\*\s*\[([^\]]+)\]\(([^)]+)\)/)
if (match) {
const newEntry = { text: match[1], link: `/${match[2]}`, children: [] }
if (level === 0) {
sidebarStructure.push(newEntry)
currentParent = sidebarStructure[sidebarStructure.length - 1]
} else {
let parent = currentParent
for (let i = 1; i < level; i++) {
parent = parent.children[parent.children.length - 1]
}
parent.children.push(newEntry)
}
}
})
sidebarStructure.forEach(removeEmptyArrays)
return sidebarStructure
}
function removeEmptyArrays(item) {
if (item.children && item.children.length === 0) {
delete item.children;
} else if (item.children) {
item.children.forEach(removeEmptyArrays);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

65
.vuepress/public/logo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -4,8 +4,72 @@ 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).
#### [3.1.2](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/3.1.0...3.1.2)
- fix(other): kubernetes error by degrading node version from v20.7.0 to v20.2.0 [`#6779`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6779)
- fix(backend): cypher statement in user locales unit test [`#6780`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6780)
- chore(release): release v3.1.1 move dkim to secrets and fix search etc. [`#6763`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6763)
- chore(other): move kubrnetes dkim from confmap to secret yaml [`#6761`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6761)
- build(other): bump @babel/preset-env from 7.22.9 to 7.22.20 in /backend [`#6741`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6741)
- build(other): bump @babel/register from 7.22.5 to 7.22.15 [`#6745`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6745)
- chore(other): add tail command as template comment to `docker-compose.yml` [`#6755`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6755)
- chore(other): upgrade node version in '.nvmrc' files to v20.6.0 [`#6758`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6758)
- build(other): bump @babel/plugin-proposal-throw-expressions from 7.8.3 to 7.22.5 in /backend [`#6742`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6742)
- build(other): bump @faker-js/faker from 8.0.2 to 8.1.0 [`#6743`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6743)
- fix(webapp): chat-only show counter if unread messages exist [`#6752`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6752)
- build(other): bump node from 20.6.0-alpine3.17 to 20.7.0-alpine3.17 in /webapp [`#6749`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6749)
- build(other): bump node from 20.6.0-alpine3.17 to 20.7.0-alpine3.17 in /backend [`#6748`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6748)
- fix(backend): post type as array in search posts query [`#6756`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6756)
- refactor(backend): remove redundant package metascraper-audio from backend [`#6724`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6724)
- test(other): update cypress related packages [`#6382`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6382)
- build(other): bump @storybook/vue from 6.3.6 to 7.4.0 in /webapp [`#6708`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6708)
- build(other): bump chai from 4.2.0 to 4.3.8 in /backend [`#6738`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6738)
- build(other): bump eslint-config-prettier from 8.8.0 to 9.0.0 in /backend [`#6737`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6737)
- build(other): bump slug from 6.1.0 to 8.2.3 [`#6716`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6716)
- build(other): bump jsonwebtoken from 8.5.1 to 9.0.2 [`#6707`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6707)
- build(other): bump expect from 29.6.1 to 29.6.4 [`#6699`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6699)
- build(other): bump node from 20.2.0-alpine3.17 to 20.6.0-alpine3.17 in /webapp [`#6709`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6709)
- build(other): bump node from 20.2.0-alpine3.17 to 20.6.0-alpine3.17 in /backend [`#6710`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6710)
- build(other): bump actions/cache from 3.3.1 to 3.3.2 [`#6714`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6714)
- build(other): bump actions/checkout from 3 to 4 [`#6713`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6713)
- Bump @storybook/vue from 6.3.6 to 7.4.0 in /webapp [`8113d47`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/8113d47dfcbfa0a63ae1f035d9d24a4c548d2089)
- Revert "update cypress packages" [`2229baf`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/2229baff6fb74d92ed395fb90a1421f994368a20)
- update cypress packages [`dbedcf9`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/dbedcf901d3040d1a6a8db62170bdea86d020bb1)
#### [3.1.0](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/3.0.4...3.1.0)
> 13 September 2023
- chore(release): release v3.1.0 use of dkim in deployment [`#6733`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6733)
- chore(other): use dkim values in helm script of backend [`#6731`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6731)
- fix(other): add global package.json to workflow file filters [`#6706`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6706)
- Release v3.1.0 [`6276d87`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/6276d87c6a427438c5fbf56c0f7bc414293e671d)
- Fix super fluid spaces [`ecdaf83`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/ecdaf83ac57bd4186f064d891d2570ce2438d47f)
- Use DKIM values in Helm script of backend [`2ea98b1`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/2ea98b1900c1b33712a2456dde6ba3dfb6d95b00)
#### [3.0.4](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/3.0.3...3.0.4)
> 12 September 2023
- chore(other): release v3.0.4 fix group link on map, embed backend shot down and bug on post language detect [`#6725`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6725)
- fix(other): fix backup script for neo4j v4 [`#6662`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6662)
- fix(other): fix workflow cache cleanup fail [`#6722`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6722)
- fix(backend): fix post language detection [`#6720`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6720)
- fix(webapp): add jsconfig.json to navigate in webapp. [`#6645`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6645)
- fix(backend): metascraper crash [`#6704`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6704)
- build(other): bump aws-sdk from 2.652.0 to 2.1425.0 in /backend [`#6651`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6651)
- build(other): bump @babel/preset-env from 7.9.5 to 7.22.9 in /backend [`#6578`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6578)
- build(other): bump @babel/preset-env from 7.22.7 to 7.22.9 [`#6572`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6572)
- build(other): bump dotenv from 8.6.0 to 16.3.1 [`#6483`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6483)
- Bump @babel/preset-env from 7.9.5 to 7.22.9 in /backend [`ae0c6f1`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/ae0c6f12bd86c39b33a2b48c2eeb0eccb880821c)
- Revert "Revert "Revert "update metascraper packages""" [`7fdc5e8`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/7fdc5e8f5ed8e191763acfcd74c510138145f612)
- Revert "Revert "update metascraper packages"" [`d5c1421`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/d5c142129291264d5508b3f32b8500c2451a5f39)
#### [3.0.3](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/3.0.2...3.0.3)
> 4 September 2023
- chore(release): release v3.0.3 fix chat avatar error, adjust layout of filter and enable e-mail dkim [`#6702`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6702)
- build(other): bump @babel/core from 7.22.8 to 7.22.9 [`#6573`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6573)
- feat(backend): implement dkim config for nodemailer [`#6692`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6692)
- fix(webapp): filtermenu mobile bug [`#6694`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6694)
@ -13,7 +77,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- fix(webapp): fix the group link in the map [`#6698`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6698)
- Bump @babel/core from 7.22.8 to 7.22.9 [`209390a`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/209390a7e026b03ee92f7b1ecb3b1a7b3b2e0232)
- Write documentation for DKIM e-mail setting [`9f5d32e`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/9f5d32e527151854f1888614c59e0aa5f2b504d0)
- Refine DKIM config for Nodemailer [`28665bd`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/28665bd175236d2e00299fe895cd5901bfe7e499)
- Release v3.0.3 [`7d761c2`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/7d761c262a6e7bf6382cc49148c55ac8037db12a)
#### [3.0.2](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/3.0.1...3.0.2)

View File

@ -1,10 +1,10 @@
# CONTRIBUTING
Thank you so much for thinking of contributing to the [ocelot.social](https://ocelot.social) project! It's awesome you're here, we really appreciate it. :-\)
Thank you so much for thinking of contributing to the <!-- [ -->ocelot.social<!-- ](https://ocelot.social) --> project! It's awesome you're here, we really appreciate it. :-\)
## Getting Set Up
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](/SUMMARY.md).
Instructions for how to install all the necessary software and some code guidelines can be found in our main [Readme](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/README.md) or in our [documentation](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/SUMMARY.md).
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):
@ -36,7 +36,7 @@ Every pull request needs to:
## Contribution Flow For Open Source Contributors
See [contributing in main README.md](/README.md#contributing)
See [contributing in main README.md](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/README.md#contributing)
## The Team
@ -48,6 +48,9 @@ You can talk to our core team on [Discord](https://discord.gg/AJSX9DCSUA). And o
* Moriz (@Mogge)
* Wolle (@Tirokk)
* Alex (@ogerly)
* Hannes (@elweyn5803)
* Mathias (@mahula)
* Markus (@maeckes#1133)
<!-- * Robert (@roschaefer)
* Matt (@mattwr18)

176
README.md
View File

@ -2,15 +2,17 @@
[![Build Status Test](https://github.com/Ocelot-Social-Community/Ocelot-Social/actions/workflows/test.yml/badge.svg)](https://github.com/Ocelot-Social-Community/Ocelot-Social/actions)
[![Build Status Publish](https://github.com/Ocelot-Social-Community/Ocelot-Social/actions/workflows/publish.yml/badge.svg)](https://github.com/Ocelot-Social-Community/Ocelot-Social/actions)
[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/LICENSE.md)
[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/LICENSE.md)
[![Discord Channel](https://img.shields.io/discord/489522408076738561.svg)](https://discord.gg/AJSX9DCSUA)
[![Open Source Helpers](https://www.codetriage.com/ocelot-social-community/ocelot-social/badges/users.svg)](https://www.codetriage.com/ocelot-social-community/ocelot-social)
[ocelot.social](https://ocelot.social) is free and open source software program code to run social networks. Its development is supported by a community of programmers and interested network operators.
<!-- [ -->Ocelot.social<!-- ](<https://ocelot.social>) --> is free and open source software program code to run social networks. Its development is supported by a community of programmers and interested network operators.
<!-- markdownlint-disable MD033 -->
<p align="center">
<a href="https://ocelot.social" target="_blank"><img src="webapp/static/img/custom/logo-squared.svg" alt="ocelot.social" width="40%" height="40%"></a>
<!-- <a href="https://ocelot.social" target="_blank"> -->
<img src="https://raw.githubusercontent.com/Ocelot-Social-Community/Ocelot-Social/master/webapp/static/img/custom/logo-squared.svg" alt="ocelot.social" width="40%" height="40%">
<!-- </a> -->
</p>
<!-- markdownlint-enable MD033 -->
@ -18,36 +20,45 @@ Our goal is to enable people to participate fairly and equally in online social
We therefore consider it desirable that operators offer such networks so that people can choose where they want to be on the move.
At the same time, it should be possible in the future to link these networks with each other (ActivityPub, Fediverse), so that users can also connect with people from other networks - for example by making friends or following posts or other contributions.
Our vision for the future is that at some point it should be possible to link these networks together (ActivityPub, Fediverse) so that users can also connect with people from other networks - for example, by friending them or following posts or other contributions.
If you would like to help set up this capability with us, please contact us.
In other words, we are interested in a network of networks and in keeping the data as close as possible to the user and the operator they trusts.
## Screenshots
<!-- markdownlint-disable MD033 -->
<img src="https://user-images.githubusercontent.com/17728384/218597429-554e4082-3906-4721-8f68-0c13146fc218.png" alt="Post feed" title="Post feed" />
<!-- markdownlint-enable MD033 -->
Check out more screenshots [here](/wiki/en:Screenshots).
Check out more screenshots [here](https://github.com/Ocelot-Social-Community/Ocelot-Social/wiki/en:Screenshots).
## Features
Ocelot.social networks feature:
* <strong>user accounts</strong>
* <strong>user roles</strong>
* <strong>posts</strong> and <strong>comments</strong>
* <strong>groups</strong>
* <strong>maps</strong>
* <strong>search</strong>
* <strong>filters</strong>
* and more …
Ocelot.social networks features:
Check out the [full feature list](/wiki/en:FAQ#what-are-the-features).
- **news feed**
- **posts**
- as **articles** and **events**
- **comments**
- **filter**
- **search**
- **groups**
- **map**
- **user accounts**
- **user roles**
- make your own **branded network**
- and more …
Check out the [full feature list](https://github.com/Ocelot-Social-Community/Ocelot-Social/wiki/en:FAQ#what-are-the-features).
## User Guide and Frequently Asked Questions
In the [wiki](/wiki) you can find more information.
In the [wiki](https://github.com/Ocelot-Social-Community/Ocelot-Social/wiki) you can find more information.
* [User Guide](/wiki/en:User-Guide)
* [Frequently Asked Questions](/wiki/en:FAQ)
- [User Guide](https://github.com/Ocelot-Social-Community/Ocelot-Social/wiki/en:User-Guide)
- [Frequently Asked Questions](https://github.com/Ocelot-Social-Community/Ocelot-Social/wiki/en:FAQ)
## Demo
@ -57,27 +68,28 @@ Try out our live demo network, see [here](#live-demo-and-developer-logins).
If you're wondering how you could help, there are plenty of ways, e.g.:
* Spread the good word about ocelot.social to make it more popular:
* Add the link [ocelot.social](https://ocelot.social) to your website.
* Give ocelot.social a Like at https://alternativeto.net/software/ocelot-social/.
* Star our project on GitHub at https://github.com/Ocelot-Social-Community/Ocelot-Social/.
* Promote it on your social networks.
* Tell your friends about it by word-of-mouth.
* Write a press article on ocelot.social or contact the editorial office of your local newspage or radio station.
* Take a [good first issue](https://github.com/Ocelot-Social-Community/Ocelot-Social/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) or issues that need help. Make sure to read [CONTRIBUTING.md](/CONTRIBUTING.md) first though.
* Testing and [reporting](/issues/new/choose) bugs.
* Translating: Please [contact us](#contact).
* Reviewing and testing pull requests.
- Spread the good word about ocelot.social to make it more popular:
- Add the link <!-- [ -->ocelot.social<!-- ](https://ocelot.social)--> to your website.
- Give ocelot.social a Like at <https://alternativeto.net/software/ocelot-social/>.
- Star our project on GitHub at <https://github.com/Ocelot-Social-Community/Ocelot-Social/>.
- Promote it on your social networks.
- Tell your friends about it by word-of-mouth.
- Write a press article on ocelot.social or contact the editorial office of your local news page or radio station.
- Take a [good first issue](https://github.com/Ocelot-Social-Community/Ocelot-Social/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) or issues that need help. Make sure to read [CONTRIBUTING.md](./CONTRIBUTING.md) first though.
- Testing and [reporting](https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/new/choose) bugs.
- Translating: Please [contact us](#contact).
- Reviewing and testing pull requests.
## Donate
## Donate
Your donation is very welcome and helps to enhance and improve the network. This software is mostly developped and maintained by the association [busFaktor() e.V.](https://www.busfaktor.org/en). Please support us with a [donation](https://www.busfaktor.org/en/donations) to busFaktor() e.V.. Thanks a lot! ❤️
Your donation is very welcome and helps to enhance and improve the network. This software is mostly developed and maintained by the association [busFaktor() e.V.](https://www.busfaktor.org/en) . Please support us with a [donation](https://www.busfaktor.org/en/donations) to busFaktor() e.V. . Thanks a lot! ❤️
## Contact
Are you interested in operating your own ocelot.social network or becoming a user? Please contact us here:
* [hello@ocelot.social](mailto:hello@ocelot.social)
* [Discord](https://discord.com/invite/DFSjPaX)
- [hello@ocelot.social](mailto:hello@ocelot.social)
- our developer chat on [Discord](https://discord.gg/AJSX9DCSUA)
## For Developers and Contributors
@ -90,17 +102,17 @@ Have a look into our short video:
There are three important directories:
* [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
* [Cypress](./cypress) contains end-to-end tests and executable feature specifications
- [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
- [Cypress](./cypress) contains end-to-end tests and executable feature specifications
In order to setup the application and start to develop features you have to
setup **frontend** and **backend**.
setup **webapp** and **backend**.
There are two approaches:
1. [Local](#local-installation) installation, which means you have to take care of dependencies yourself.
2. **Or** Install everything through [Docker](#docker-installation) which takes care of dependencies for you.
2. **Or** install everything through [Docker](#docker-installation) which takes care of dependencies for you.
### Installation
@ -126,13 +138,13 @@ Change into the new folder.
$ cd Ocelot-Social
```
### Live Demo And Developer Logins
### Live Demo and Developer Logins
**Try out our deployed [development environment](https://stage.ocelot.social).**
**Try out our deployed <!-- [ -->development environment<!--](https://stage.ocelot.social)-->.**
Visit our staging networks:
* central staging network: [stage.ocelot.social](https://stage.ocelot.social)
- central staging network: <!-- [ -->stage.ocelot.social<!-- ](https://stage.ocelot.social)-->
<!-- - rebranded staging network: [rebrand.ocelot.social](https://stage.ocelot.social). -->
#### Login
@ -151,19 +163,14 @@ Docker is a software development container tool that combines software and its d
##### General Installation of Docker
There are [several ways to install Docker CE](https://docs.docker.com/install/) on your computer or server.
* [install Docker Desktop on macOS](https://docs.docker.com/docker-for-mac/install/)
* [install Docker Desktop on Windows](https://docs.docker.com/docker-for-windows/install/)
* [install Docker CE on Linux](https://docs.docker.com/install/)
There are [several ways to install Docker](https://docs.docker.com/get-docker/) on your computer or server.
Check the correct Docker installation by checking the version before proceeding. E.g. we have the following versions:
```bash
# use Docker version 24.0.6 or newer
# includes Docker Compose
$ docker --version
Docker version 18.09.2
$ docker-compose --version
docker-compose version 1.23.2
```
##### Start Ocelot-Social via Docker-Compose
@ -182,14 +189,14 @@ For Development:
```bash
# in main folder
$ docker-compose up
$ docker compose up
```
For Production:
```bash
# in main folder
$ docker-compose -f docker-compose.yml up
$ docker compose -f docker-compose.yml up
```
This will start all required Docker containers.
@ -198,7 +205,7 @@ Make sure your database is running on `http://localhost:7474/browser/`.
Prepare database once before you start by running the following command in a second terminal:
```bash
# in main folder while docker-compose is up
# in main folder while docker compose is up
$ docker compose exec backend yarn run db:migrate init
$ docker compose exec backend yarn run db:migrate up
```
@ -206,17 +213,17 @@ $ docker compose exec backend yarn run db:migrate up
Then clear and seed database by running the following command as well in the second terminal:
```bash
# in main folder while docker-compose is up
$ docker-compose exec backend yarn run db:reset
$ docker-compose exec backend yarn run db:seed
# in main folder while docker compose is up
$ docker compose exec backend yarn run db:reset
$ docker compose exec backend yarn run db:seed
```
For a closer description see [backend README.md](./backend/README.md).
For a full documentation see [SUMMARY](./SUMMARY.md).
For a closer description see [backend](./backend/README.md).
For a full documentation of the Docker installation see [summary](./SUMMARY.md).
#### Local Installation
For a full documentation see [SUMMARY](./SUMMARY.md).
For a full documentation of the local installation see [summary](./SUMMARY.md).
### Contributing
@ -225,7 +232,9 @@ To have the necessary permission to push directly to this repository, please acc
We are happy if you fork our repository, but we don't recommend it for development. You do not need a fork.
Clone this repository locally as [described above](#clone-the-repository), create your branch named `<issue-number>-<description>`, add your code and push your branch to this repository. Then create a PR by comparing it to our `master`.
Clone this repository locally as [described above](#clone-the-repository), create your branch named `<issue-number>-<description>`, add your code and push your branch direct to this repository. Then create a PR by comparing it to our `master`.
**_!!! Be aware:_** Please don't compare from a fork, because the tests are breaking caused by credential problems.
Please run the following commands before you push:
@ -242,37 +251,52 @@ $ yarn locales --fix
$ yarn test
```
Check out our [contribution guideline](./CONTRIBUTING.md), too!
Check out our [contribution guideline](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/CONTRIBUTING.md), too!
#### Developer Chat
Join our friendly open-source community on [Discord](https://discord.gg/AJSX9DCSUA) :heart_eyes_cat:
Just introduce yourself at `#introduce-yourself` and mention a mentor or `@@Mentors` to get you onboard :neckbeard:
Join our friendly open-source community on [Discord](https://discord.gg/AJSX9DCSUA) 😻
Just introduce yourself at `#introduce-yourself` and mention a mentor or `@@Mentors` to get you onboard 🤓
We give write permissions to every developer who asks for it. Just text us on
[Discord](https://discord.gg/AJSX9DCSUA).
### Deployment
Deployment methods can be found in the [Ocelot-Social-Deploy-Rebranding](https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding) repository.
Deployment methods can be found in our `deployment` folder described in the [README](./deployment/README.md).
Our branding template is our [stage.ocelot.social](https://github.com/Ocelot-Social-Community/stage.ocelot.social) repository.
Place your branding repository inside `deployment/configurations`.
The only deployment method in this repository for development purposes as described above is `docker-compose`.
The only deployment method in this repository for production purposes is [Kubernetes](https://kubernetes.io) for now.
But we just started to develop a deployment for [Docker Compose](https://docs.docker.com/compose/) as well.
The only deployment method with branding in this repository for development purposes as described above is [Docker Compose](https://docs.docker.com/compose/):
```bash
# in folder deployment/
# set your branding folder name in .env
# then run
$ docker compose up
```
The code is branded automatically.
To setup the Neo4j database see above.
### Technology Stack
* [VueJS](https://vuejs.org/)
* [NuxtJS](https://nuxtjs.org/)
* [GraphQL](https://graphql.org/)
* [NodeJS](https://nodejs.org/en/)
* [Neo4J](https://neo4j.com/)
- [VueJS](https://vuejs.org/)
- [NuxtJS](https://nuxtjs.org/)
- [GraphQL](https://graphql.org/)
- [NodeJS](https://nodejs.org/en/)
- [Neo4J](https://neo4j.com/)
#### For Testing
* [Cypress](https://docs.cypress.io/)
* [Storybook](https://storybook.js.org/)
* [Jest](https://jestjs.io/)
* [Vue Test Utils](https://vue-test-utils.vuejs.org/)
* [ESLint](https://eslint.org/)
- [Cypress](https://docs.cypress.io/)
- [Storybook](https://storybook.js.org/)
- [Jest](https://jestjs.io/)
- [Vue Test Utils](https://vue-test-utils.vuejs.org/)
- [ESLint](https://eslint.org/)
### Attributions
@ -280,7 +304,9 @@ Locale Icons made by [Freepik](http://www.freepik.com/) from [www.flaticon.com](
Browser compatibility testing with [BrowserStack](https://www.browserstack.com/).
<img alt="BrowserStack Logo" src=".gitbook/assets/browserstack-logo.svg" width="256">
<!-- markdownlint-disable MD033 -->
<img alt="BrowserStack Logo" src="https://raw.githubusercontent.com/Ocelot-Social-Community/Ocelot-Social/master/.gitbook/assets/browserstack-logo.svg" width="256">
<!-- markdownlint-enable MD033 -->
### License

View File

@ -1,24 +1,22 @@
# Table of contents
* [Introduction](README.md)
* [Edit this Documentation](edit-this-documentation.md)
* [Neo4J](neo4j/README.md)
* [Backend](backend/README.md)
* [GraphQL](backend/graphql.md)
* [neo4j-graphql-js](backend/neo4j-graphql-js.md)
* [Webapp](webapp/README.md)
* [Webapp (Frontend)](webapp/README.md)
* [Components](webapp/components.md)
* [HTML](webapp/html.md)
* [SCSS](webapp/scss.md)
* [Vue](webapp/vue.md)
* [Testing Guide](testing.md)
* [End-to-end tests](cypress/README.md)
* [Frontend tests](webapp/testing.md)
* [Backend tests](backend/testing.md)
* [Docker More Closely](DOCKER_MORE_CLOSELY.md)
* [End-to-end Tests](cypress/README.md)
* [Webapp (Frontend) Tests](webapp/testing.md)
* [Backend Tests](backend/testing.md)
* [Deployment](deployment/README.md)
* [Contributing](CONTRIBUTING.md)
* [Feature Specification](cypress/features.md)
* [Code of conduct](CODE_OF_CONDUCT.md)
* [Code of Conduct](CODE_OF_CONDUCT.md)
* [Documentation](documentation.md)
* [License](LICENSE.md)

View File

@ -83,8 +83,8 @@ More details about our GraphQL playground and how to use it with ocelot.social c
Database indexes and constraints need to be created and upgraded when the database and the backend are running:
{% tabs %}
{% tab title="Docker" %}
::: tabs
@tab:active Docker
```bash
# in main folder while docker-compose is running
@ -102,8 +102,7 @@ $ docker compose exec backend /bin/sh -c "yarn prod:migrate init"
$ docker exec backend yarn run db:migrate up
```
{% endtab %}
{% tab title="Without Docker" %}
@tab Without Docker
```bash
# in folder backend/ while database is running
@ -116,16 +115,15 @@ yarn run db:migrate init
yarn run db:migrate up
```
{% endtab %}
{% endtabs %}
:::
#### Seed Database
If you want your backend to return anything else than an empty response, you
need to seed your database:
{% tabs %}
{% tab title="Docker" %}
::: tabs
@tab:active Docker
In another terminal run:
@ -147,8 +145,7 @@ $ docker exec backend yarn run db:migrate init
$ docker exec backend yarn run db:migrate up
```
{% endtab %}
{% tab title="Without Docker" %}
@tab Without Docker
Run:
@ -164,16 +161,15 @@ To reset the database run:
$ yarn run db:reset
```
{% endtab %}
{% endtabs %}
:::
### Data migrations
Although Neo4J is schema-less,you might find yourself in a situation in which
you have to migrate your data e.g. because your data modeling has changed.
{% tabs %}
{% tab title="Docker" %}
::: tabs
@tab:active Docker
Generate a data migration file:
@ -190,8 +186,7 @@ To run the migration:
$ docker exec backend yarn run db:migrate up
```
{% endtab %}
{% tab title="Without Docker" %}
@tab Without Docker
Generate a data migration file:
@ -208,16 +203,15 @@ To run the migration:
$ yarn run db:migrate up
```
{% endtab %}
{% endtabs %}
:::
## Testing
**Beware**: We have no multiple database setup at the moment. We clean the
database after each test, running the tests will wipe out all your data!
{% tabs %}
{% tab title="Docker" %}
::: tabs
@tab:active Docker
Run the unit tests:
@ -226,9 +220,7 @@ Run the unit tests:
$ docker exec backend yarn run test
```
{% endtab %}
{% tab title="Without Docker" %}
@tab Without Docker
Run the unit tests:
@ -237,5 +229,4 @@ Run the unit tests:
$ yarn run test
```
{% endtab %}
{% endtabs %}
:::

View File

@ -2,12 +2,13 @@
GraphQL is a data query language which provides an alternative to REST and ad-hoc web service architectures. It allows clients to define the structure of the data required, and exactly the same structure of the data is returned from the server.
![GraphQL Playground](../../../.gitbook/assets/graphql-playground%20%281%29.png)
We have a closer description for the [GraphQL Playground](./src/graphql/GraphQL-Playground.md).
![GraphQL Playground](../.gitbook/assets/graphql-playground%20%281%29.png)
## Middleware keeps resolvers clean
![](../.gitbook/assets/grafik-4.png)
![Middleware schema](../.gitbook/assets/grafik-4.png)
A well-organized codebase is key for the ability to maintain and easily introduce changes into an app. Figuring out the right structure for your code remains a continuous challenge - especially as an application grows and more developers are joining a project.

View File

@ -7,11 +7,12 @@ module.exports = {
'!**/node_modules/**',
'!**/test/**',
'!**/build/**',
'!**/src/**/?(*.)+(spec|test).ts?(x)'
'!**/src/**/?(*.)+(spec|test).ts?(x)',
'!**/src/db/**'
],
coverageThreshold: {
global: {
lines: 67,
lines: 90,
},
},
testMatch: ['**/src/**/?(*.)+(spec|test).ts?(x)'],

View File

@ -1,6 +1,6 @@
{
"name": "ocelot-social-backend",
"version": "3.0.3",
"version": "3.1.2",
"description": "GraphQL Backend for ocelot.social",
"repository": "https://github.com/Ocelot-Social-Community/Ocelot-Social",
"author": "ocelot.social Community",
@ -26,8 +26,8 @@
"@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.22.9",
"@babel/plugin-proposal-throw-expressions": "^7.22.5",
"@babel/preset-env": "~7.22.20",
"@babel/register": "^7.9.0",
"@sentry/node": "^5.15.4",
"apollo-cache-inmemory": "~1.6.5",
@ -45,7 +45,7 @@
"cheerio": "~1.0.0-rc.3",
"cors": "~2.8.5",
"cross-env": "~7.0.3",
"dotenv": "~8.2.0",
"dotenv": "~16.3.1",
"express": "^4.17.1",
"graphql": "^14.6.0",
"graphql-middleware": "~4.0.2",
@ -61,7 +61,6 @@
"lodash": "~4.17.14",
"merge-graphql-schemas": "^1.7.8",
"metascraper": "^5.33.5",
"metascraper-audio": "^5.34.4",
"metascraper-author": "^5.33.5",
"metascraper-date": "^5.33.5",
"metascraper-description": "^5.33.5",
@ -75,7 +74,7 @@
"metascraper-url": "^5.34.2",
"metascraper-video": "^5.33.5",
"metascraper-youtube": "^5.33.5",
"migrate": "^2.0.0",
"migrate": "^2.0.1",
"mime-types": "^2.1.26",
"minimatch": "^3.0.4",
"mustache": "^4.2.0",
@ -86,12 +85,12 @@
"nodemailer": "^6.4.4",
"nodemailer-html-to-text": "^3.2.0",
"request": "~2.88.2",
"sanitize-html": "~1.22.0",
"sanitize-html": "~2.11.0",
"slug": "~6.0.0",
"subscriptions-transport-ws": "^0.9.19",
"trunc-html": "~1.1.2",
"uuid": "~8.3.2",
"validator": "^13.9.0",
"validator": "^13.11.0",
"xregexp": "^4.3.0"
},
"devDependencies": {
@ -101,13 +100,11 @@
"@typescript-eslint/eslint-plugin": "^5.57.1",
"@typescript-eslint/parser": "^5.57.1",
"apollo-server-testing": "~2.11.0",
"chai": "~4.2.0",
"cucumber": "~6.0.5",
"eslint": "^8.37.0",
"eslint-config-prettier": "^8.8.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-standard": "^17.0.0",
"eslint-import-resolver-typescript": "^3.5.4",
"eslint-plugin-import": "^2.27.5",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.29.0",
"eslint-plugin-jest": "^27.2.1",
"eslint-plugin-n": "^15.7.0",
"eslint-plugin-prettier": "^4.2.1",

View File

@ -0,0 +1,68 @@
import { getDriver } from '../../db/neo4j'
export const description = `
Transform event start and end date of format 'YYYY-MM-DD HH:MM:SS' in CEST
to ISOString in UTC.
`
export async function up(next) {
const driver = getDriver()
const session = driver.session()
const transaction = session.beginTransaction()
try {
const events = await transaction.run(`
MATCH (event:Event)
WHERE NOT event.eventStart CONTAINS 'T'
RETURN event.id, event.eventStart, event.eventEnd
`)
for (const event of events.records) {
let [id, eventStart, eventEnd] = event
let date = new Date(eventStart)
date.setHours(date.getHours() - 1)
eventStart = date.toISOString()
if (eventEnd) {
date = new Date(eventEnd)
date.setHours(date.getHours() - 1)
eventEnd = date.toISOString()
}
await transaction.run(`
MATCH (e:Event { id: '${id}' })
SET e.eventStart = '${eventStart}'
SET (CASE WHEN exists(e.eventEnd) THEN e END).eventEnd = '${eventEnd}'
RETURN e
`)
}
await transaction.commit()
next()
} catch (error) {
// eslint-disable-next-line no-console
console.log(error)
await transaction.rollback()
// eslint-disable-next-line no-console
console.log('rolled back')
throw new Error(error)
} finally {
session.close()
}
}
export async function down(next) {
const driver = getDriver()
const session = driver.session()
const transaction = session.beginTransaction()
try {
// No sense in running this down
next()
} catch (error) {
// eslint-disable-next-line no-console
console.log(error)
await transaction.rollback()
// eslint-disable-next-line no-console
console.log('rolled back')
throw new Error(error)
} finally {
session.close()
}
}

View File

@ -1,5 +1,7 @@
# GraphQL Playground
![GraphQL Playground](../../../.gitbook/assets/graphql-playground%20%281%29.png)
***Attention:** For using the GraphQL Playground set `DEBUG=true` in your backend `.env`, see `.env.template`!*
To use GraphQL Playground, we need to know some basics:

View File

@ -1,35 +1,11 @@
import Factory, { cleanDatabase } from '../db/factories'
import { getDriver, getNeode } from '../db/neo4j'
import decode from './decode'
import encode from './encode'
const driver = getDriver()
const neode = getNeode()
// here is the decoded JWT token:
// {
// role: 'user',
// locationName: null,
// name: 'Jenny Rostock',
// about: null,
// avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/sasha_shestakov/128.jpg',
// id: 'u3',
// email: 'user@example.org',
// slug: 'jenny-rostock',
// iat: 1550846680,
// exp: 1637246680,
// aud: 'http://localhost:3000',
// iss: 'http://localhost:4000',
// sub: 'u3'
// }
// !!! if the token expires go into the GraphQL Playground in the browser at 'http://localhost:4000' with a running backend and a seeded Neo4j database
// now do the login mutation:
// mutation {
// login(email:"user@example.org", password:"1234")
// }
// replace this token here with the one you received as the result
export const validAuthorizationHeader =
'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6InUzIiwibmFtZSI6Ikplbm55IFJvc3RvY2siLCJzbHVnIjoiamVubnktcm9zdG9jayIsImlhdCI6MTYzNzY0NDMwMCwiZXhwIjoxNzAwNzU5NTAwLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAiLCJzdWIiOiJ1MyJ9.ispIfRfgkXuYoIhKx7x2jPxgvHDJVv1ogMycLmfUnsk'
beforeAll(async () => {
await cleanDatabase()
})
@ -75,14 +51,8 @@ describe('decode', () => {
})
describe('given valid JWT Bearer token', () => {
beforeEach(() => {
authorizationHeader = validAuthorizationHeader
})
it('returns null', returnsNull)
describe('and corresponding user in the database', () => {
let user
let user, validAuthorizationHeader
beforeEach(async () => {
user = await Factory.build(
'user',
@ -99,10 +69,11 @@ describe('decode', () => {
email: 'user@example.org',
},
)
validAuthorizationHeader = encode(await user.toJson())
})
it('returns user object without email', async () => {
await expect(decode(driver, authorizationHeader)).resolves.toMatchObject({
await expect(decode(driver, validAuthorizationHeader)).resolves.toMatchObject({
role: 'user',
name: 'Jenny Rostock',
id: 'u3',
@ -113,7 +84,7 @@ describe('decode', () => {
it('sets `lastActiveAt`', async () => {
let user = await neode.first('User', { id: 'u3' })
await expect(user.toJson()).resolves.not.toHaveProperty('lastActiveAt')
await decode(driver, authorizationHeader)
await decode(driver, validAuthorizationHeader)
user = await neode.first('User', { id: 'u3' })
await expect(user.toJson()).resolves.toMatchObject({
lastActiveAt: expect.any(String),
@ -129,7 +100,7 @@ describe('decode', () => {
await expect(user.toJson()).resolves.toMatchObject({
lastActiveAt: '2019-10-03T23:33:08.598Z',
})
await decode(driver, authorizationHeader)
await decode(driver, validAuthorizationHeader)
user = await neode.first('User', { id: 'u3' })
await expect(user.toJson()).resolves.toMatchObject({
// should be a different time by now ;)
@ -152,6 +123,15 @@ describe('decode', () => {
it('returns null', returnsNull)
})
describe('and NO corresponding user in the database', () => {
beforeEach(async () => {
await cleanDatabase()
authorizationHeader = validAuthorizationHeader
})
it('returns null', returnsNull)
})
})
})
})

View File

@ -131,4 +131,25 @@ describe('languagesMiddleware', () => {
},
})
})
describe('detects no language', () => {
it('has default language', async () => {
variables = {
...variables,
content: '',
}
await expect(
mutate({
mutation: createPostMutation,
variables,
}),
).resolves.toMatchObject({
data: {
CreatePost: {
language: 'en',
},
},
})
})
})
})

View File

@ -1,20 +1,24 @@
import LanguageDetect from 'languagedetect'
import { removeHtmlTags } from '../helpers/cleanHtml'
const setPostLanguage = (text) => {
const setPostLanguage = (text, defaultLanguage) => {
const lngDetector = new LanguageDetect()
lngDetector.setLanguageType('iso2')
return lngDetector.detect(removeHtmlTags(text), 1)[0][0]
let languages = lngDetector.detect(removeHtmlTags(text), 1)
if (!(Array.isArray(languages) && languages.length > 0)) {
languages = [[defaultLanguage, 1.0]]
}
return languages[0][0]
}
export default {
Mutation: {
CreatePost: async (resolve, root, args, context, info) => {
args.language = await setPostLanguage(args.content)
args.language = await setPostLanguage(args.content, context.user.locale)
return resolve(root, args, context, info)
},
UpdatePost: async (resolve, root, args, context, info) => {
args.language = await setPostLanguage(args.content)
args.language = await setPostLanguage(args.content, context.user.locale)
return resolve(root, args, context, info)
},
},

View File

@ -20,7 +20,6 @@ const metascraper = Metascraper([
require('metascraper-publisher')(),
require('metascraper-title')(),
require('metascraper-url')(),
require('metascraper-audio')(),
require('metascraper-soundcloud')(),
require('metascraper-video')(),
require('metascraper-youtube')(),

View File

@ -34,6 +34,8 @@ const validateEventDate = (dateString) => {
const date = new Date(dateString)
if (date.toString() === 'Invalid Date')
throw new UserInputError('Event start date must be a valid date!')
if (date.toISOString() !== dateString)
throw new UserInputError('Event start date must be in ISO format!')
const now = new Date()
if (date.getTime() < now.getTime()) {
throw new UserInputError('Event start date must be in the future!')
@ -44,6 +46,8 @@ const validateEventEnd = (start, end) => {
const endDate = new Date(end)
if (endDate.toString() === 'Invalid Date')
throw new UserInputError('Event end date must be a valid date!')
if (endDate.toISOString() !== end)
throw new UserInputError('Event end date must be in ISO format!')
const startDate = new Date(start)
if (endDate < startDate)
throw new UserInputError('Event end date must be a after event start date!')

View File

@ -56,98 +56,97 @@ describe('given some notifications', () => {
Factory.build('user', { id: 'neighbor' }),
Factory.build('category', { id: 'cat1' }),
])
const [post1, post2, post3] = await Promise.all([
Factory.build('post', { id: 'p1', content: 'Not for you' }, { author, categoryIds }),
Factory.build(
'post',
{
id: 'p2',
content: 'Already seen post mention',
},
{
author,
categoryIds,
},
),
Factory.build(
'post',
{
id: 'p3',
content: 'You have been mentioned in a post',
},
{
author,
categoryIds,
},
),
])
const [comment1, comment2, comment3] = await Promise.all([
Factory.build(
'comment',
{
id: 'c1',
content: 'You have seen this comment mentioning already',
},
{
author,
postId: 'p3',
},
),
Factory.build(
'comment',
{
id: 'c2',
content: 'You have been mentioned in a comment',
},
{
author,
postId: 'p3',
},
),
Factory.build(
'comment',
{
id: 'c3',
content: 'Somebody else was mentioned in a comment',
},
{
author,
postId: 'p3',
},
),
])
await Promise.all([
post1.relateTo(neighbor, 'notified', {
createdAt: '2019-08-29T17:33:48.651Z',
read: false,
reason: 'mentioned_in_post',
}),
post2.relateTo(user, 'notified', {
createdAt: '2019-08-30T17:33:48.651Z',
read: true,
reason: 'mentioned_in_post',
}),
post3.relateTo(user, 'notified', {
createdAt: '2019-08-31T17:33:48.651Z',
read: false,
reason: 'mentioned_in_post',
}),
comment1.relateTo(user, 'notified', {
createdAt: '2019-08-30T15:33:48.651Z',
read: true,
reason: 'mentioned_in_comment',
}),
comment2.relateTo(user, 'notified', {
createdAt: '2019-08-30T19:33:48.651Z',
read: false,
reason: 'mentioned_in_comment',
}),
comment3.relateTo(neighbor, 'notified', {
createdAt: '2019-09-01T17:33:48.651Z',
read: false,
reason: 'mentioned_in_comment',
}),
])
const post1 = await Factory.build(
'post',
{ id: 'p1', content: 'Not for you' },
{ author, categoryIds },
)
const post2 = await Factory.build(
'post',
{
id: 'p2',
content: 'Already seen post mention',
},
{
author,
categoryIds,
},
)
const post3 = await Factory.build(
'post',
{
id: 'p3',
content: 'You have been mentioned in a post',
},
{
author,
categoryIds,
},
)
const comment1 = await Factory.build(
'comment',
{
id: 'c1',
content: 'You have seen this comment mentioning already',
},
{
author,
postId: 'p3',
},
)
const comment2 = await Factory.build(
'comment',
{
id: 'c2',
content: 'You have been mentioned in a comment',
},
{
author,
postId: 'p3',
},
)
const comment3 = await Factory.build(
'comment',
{
id: 'c3',
content: 'Somebody else was mentioned in a comment',
},
{
author,
postId: 'p3',
},
)
await post1.relateTo(neighbor, 'notified', {
createdAt: '2019-08-29T17:33:48.651Z',
read: false,
reason: 'mentioned_in_post',
})
await post2.relateTo(user, 'notified', {
createdAt: '2019-08-30T17:33:48.651Z',
read: true,
reason: 'mentioned_in_post',
})
await post3.relateTo(user, 'notified', {
createdAt: '2019-08-31T17:33:48.651Z',
read: false,
reason: 'mentioned_in_post',
})
await comment1.relateTo(user, 'notified', {
createdAt: '2019-08-30T15:33:48.651Z',
read: true,
reason: 'mentioned_in_comment',
})
await comment2.relateTo(user, 'notified', {
createdAt: '2019-08-30T19:33:48.651Z',
read: false,
reason: 'mentioned_in_comment',
})
await comment3.relateTo(neighbor, 'notified', {
createdAt: '2019-09-01T17:33:48.651Z',
read: false,
reason: 'mentioned_in_comment',
})
})
describe('notifications', () => {

View File

@ -374,6 +374,31 @@ describe('CreatePost', () => {
})
})
describe('with event start in no ISO format', () => {
it('throws an error', async () => {
const now = new Date()
const eventStart = new Date(now.getFullYear(), now.getMonth() - 1).toISOString()
await expect(
mutate({
mutation: createPostMutation(),
variables: {
...variables,
postType: 'Event',
eventInput: {
eventStart: eventStart.split('T')[0],
},
},
}),
).resolves.toMatchObject({
errors: [
{
message: 'Event start date must be in ISO format!',
},
],
})
})
})
describe('with event start date in the past', () => {
it('throws an error', async () => {
const now = new Date()
@ -423,6 +448,32 @@ describe('CreatePost', () => {
})
})
describe('with valid start date and not ISO formated end date', () => {
it('throws an error', async () => {
const now = new Date()
const eventEnd = new Date(now.getFullYear(), now.getMonth() + 2).toISOString()
await expect(
mutate({
mutation: createPostMutation(),
variables: {
...variables,
postType: 'Event',
eventInput: {
eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
eventEnd: eventEnd.split('T')[0],
},
},
}),
).resolves.toMatchObject({
errors: [
{
message: 'Event end date must be in ISO format!',
},
],
})
})
})
describe('with valid start date and end date before start date', () => {
it('throws an error', async () => {
const now = new Date()

View File

@ -110,7 +110,13 @@ const searchResultPromise = async (session, setup, params) => {
}
const searchResultCallback = (result) => {
return result.records.map((r) => r.get('result'))
const response = result.records.map((r) => r.get('result'))
if (Array.isArray(response) && response.length && response[0].__typename === 'Post') {
response.forEach((post) => {
post.postType = [post.postType]
})
}
return response
}
const countResultCallback = (result) => {

View File

@ -208,7 +208,7 @@ describe('userMiddleware', () => {
}
await mutate({ mutation: updateUserMutation, variables })
const locations = await neode.cypher(
`MATCH (city:Location)-[:IS_IN]->(state:Location)-[:IS_IN]->(country:Location) return city {.*}, state {.*}, country {.*}`,
`MATCH (city:Location)-[:IS_IN]->(district:Location)-[:IS_IN]->(state:Location)-[:IS_IN]->(country:Location) return city {.*}, state {.*}, country {.*}`,
)
expect(
locations.records.map((record) => {

View File

@ -1,2 +1,3 @@
# Unit Testing
***TODO:** To be filled in*

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,8 @@ const { parsed } = dotenv.config({ path: '../backend/.env' })
module.exports = defineConfig({
e2e: {
projectId: "qa7fe2",
defaultCommandTimeout: 10000,
defaultCommandTimeout: 60000,
pageLoadTimeout:180000,
chromeWebSecurity: false,
baseUrl: "http://localhost:3000",
specPattern: "cypress/e2e/**/*.feature",

View File

@ -14,9 +14,9 @@ The following features will be implemented. This gets done in three steps:
2. In a second step we will make our prototype publicly available with an advanced feature set including the technology and organizational structure to drive a bigger public social network.
3. In a third step all the remaining features will be implemented to build the full product.
### User Account
The implemented features can be found [here](https://github.com/Ocelot-Social-Community/Ocelot-Social/tree/master/cypress/e2e)
[Cucumber Features](https://github.com/Ocelot-Social-Community/Ocelot-Social/tree/master/cypress/integration/user_account)
### User Account
* Sign-up
* Agree to Data Privacy Statement
@ -34,8 +34,6 @@ The following features will be implemented. This gets done in three steps:
### User Profile
[Cucumber Features](https://github.com/Ocelot-Social-Community/Ocelot-Social/tree/master/cypress/integration/user_profile)
* Upload and Change Avatar
* Upload and Change Profile Picture
* Edit Social Media Accounts
@ -46,8 +44,6 @@ The following features will be implemented. This gets done in three steps:
### Dashboard
[Clickdummy](https://preview.uxpin.com/24a2ab8adcd84f9a763d87ed27251351225e0ecd#/pages/99768919/simulate/sitemap?mode=i)
* Show Link to own Profile
* Show Friends Widget
* Show Favorites Widget
@ -59,8 +55,6 @@ The following features will be implemented. This gets done in three steps:
### Posts
[Cucumber Features](https://github.com/Ocelot-Social-Community/Ocelot-Social/tree/master/cypress/integration/post)
* Creating Posts
* Persistent Links
* Upload Teaser Picture for Post
@ -85,8 +79,6 @@ The following features will be implemented. This gets done in three steps:
### Notifications
[Cucumber features](https://github.com/Ocelot-Social-Community/Ocelot-Social/tree/master/cypress/integration/notifications)
* User @-mentionings
* Notify authors for comments
* Administrative notifications to all users
@ -108,8 +100,6 @@ The following features will be implemented. This gets done in three steps:
### Blacklist
[Video](https://www.youtube.com/watch?v=-uDvvmN8hLQ)
* Blacklist Users
* Blacklist specific Terms
* Blacklist Tags
@ -117,8 +107,6 @@ The following features will be implemented. This gets done in three steps:
### Search
[Cucumber Features](https://github.com/Ocelot-Social-Community/Ocelot-Social/tree/master/cypress/integration/search)
* Search for Categories
* Search for Tags
* Fulltext Search
@ -238,8 +226,6 @@ Shows automatically related actions for existing post.
### Moderation
[Cucumber Features](https://github.com/Ocelot-Social-Community/Ocelot-Social/tree/master/cypress/integration/moderation)
* Report Button for users for doubtful Content
* Moderator Panel
* List of reported Content \(later replaced by User-Moderation\)
@ -250,8 +236,6 @@ Shows automatically related actions for existing post.
### Administration
[Cucumber Features](https://github.com/Ocelot-Social-Community/Ocelot-Social/tree/master/cypress/integration/administration)
* Provide Admin-Interface to send Users Invite Code
* Static Pages for Data Privacy Statement ...
* Create, edit and delete Announcements
@ -265,8 +249,6 @@ Shows automatically related actions for existing post.
### Internationalization
[Cucumber Features](https://github.com/Ocelot-Social-Community/Ocelot-Social/tree/master/cypress/integration/internationalization)
* Frontend UI
* Backend Error Messages

View File

@ -1,6 +1,6 @@
import { When } from "@badeball/cypress-cucumber-preprocessor";
When("I comment the following:", async text => {
When("I comment the following:", text => {
const comment = text.replace("\n", " ")
cy.task('pushValue', { name: 'lastComment', value: comment })
cy.get(".editor .ProseMirror").type(comment);

View File

@ -1,6 +1,6 @@
import { When } from "@badeball/cypress-cucumber-preprocessor";
When("I choose {string} as the title", async title => {
When("I choose {string} as the title", title => {
const lastPost = {}
lastPost.title = title.replace("\n", " ");
cy.task('pushValue', { name: 'lastPost', value: lastPost })

View File

@ -1,6 +1,6 @@
import { Then } from "@badeball/cypress-cucumber-preprocessor";
Then("the post was saved successfully", async () => {
Then("the post was saved successfully", () => {
cy.task('getValue', 'lastPost').then(lastPost => {
cy.get(".base-card > .title").should("contain", lastPost.title);
cy.get(".content").should("contain", lastPost.content);

View File

@ -1,6 +1,6 @@
import { When } from "@badeball/cypress-cucumber-preprocessor";
When("I choose the following text as content:", async text => {
When("I choose the following text as content:", text => {
cy.task('getValue', 'lastPost').then(lastPost => {
lastPost.content = text.replace("\n", " ");
cy.task('pushValue', { name: 'lastPost', value: lastPost })

View File

@ -9,8 +9,6 @@
$ export DOCKER_DEFAULT_PLATFORM=linux/amd64
```
For even more informations, see [Docker More Closely](#docker-more-closely)
### Docker Compose Override File For Apple M1 Platform
For Docker compose `up` or `build` commands, you can use our Apple M1 override file that specifies the M1 platform:
@ -27,7 +25,3 @@ $ docker compose -f docker-compose.ocelotsocial-branded.yml -f docker-compose.ap
# only once: init admin user and create indexes and constraints in Neo4j database
$ docker compose exec backend /bin/sh -c "yarn prod:migrate init"
```
## Docker More Closely In Main Code
To get more informations about the Apple M1 platform and to analyze the Docker builds etc. you find our documentation in our main code, [here](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/DOCKER_MORE_CLOSELY.md).

View File

@ -11,7 +11,7 @@ $ minikube dashboard
This will give you an overview. Some of the steps below need some timing to make resources available to other dependent deployments. Keeping an eye on the dashboard is a great way to check that.
Follow the installation instruction for [Kubernetes with Helm](./kubernetes/README.md).
Follow the installation instruction for [Kubernetes with Helm](./src/kubernetes/README.md).
If all the pods and services have settled and everything looks green in your
minikube dashboard, expose the services you want on your host system.

View File

@ -1,7 +1,7 @@
# Ocelot.Social Deploy And Rebranding
[![Build Status Publish](https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/actions/workflows/publish.yml/badge.svg)](https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/actions)
[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/blob/LICENSE.md)
[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/blob/master/LICENSE.md)
[![Discord Channel](https://img.shields.io/discord/489522408076738561.svg)](https://discord.gg/AJSX9DCSUA)
[![Open Source Helpers](https://www.codetriage.com/ocelot-social-community/ocelot-social-deploy-rebranding/badges/users.svg)](https://www.codetriage.com/ocelot-social-community/ocelot-social-deploy-rebranding)
@ -10,17 +10,19 @@ The forked original repository is [stage.ocelot.social](https://github.com/Ocelo
<!-- markdownlint-disable MD033 -->
<p align="center">
<a href="https://ocelot.social" target="_blank"><img src="../webapp/static/img/custom/logo-squared.svg" alt="ocelot.social" width="40%" height="40%"></a>
<!-- <a href="https://ocelot.social" target="_blank"> -->
<img src="../webapp/static/img/custom/logo-squared.svg" alt="ocelot.social" width="40%" height="40%">
<!-- </a> -->
</p>
<!-- markdownlint-enable MD033 -->
## Live demo
__Try out our deployed [development environment](https://stage.ocelot.social).__
__Try out our deployed <!-- [ -->development environment<!-- ](https://stage.ocelot.social)-->.__
Visit our staging networks:
- central staging network: [stage.ocelot.social](https://stage.ocelot.social)
- central staging network: <!-- [ -->stage.ocelot.social<!-- ](https://stage.ocelot.social)-->
<!-- - rebranded staging network: [rebrand.ocelot.social](https://stage.ocelot.social). -->
Logins:
@ -39,16 +41,18 @@ Fork this repository to configure and rebrand it for your own [ocelot.social](ht
Write your own data into the main configuration file:
- [package.json](/package.json)
- [package.json](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/package.json)
Since all deployment methods described here depend on [Docker](https://docker.com) and [DockerHub](https://hub.docker.com), you need to create your own organisation on DockerHub and put its name in the [package.json](/package.json) file as your `dockerOrganisation`.
Since all deployment methods described here depend on [Docker](https://docker.com) and [DockerHub](https://hub.docker.com), you need to create your own organisation on DockerHub and put its name in the [package.json](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/package.json) file as your `dockerOrganisation`.
### Configure And Branding
The next step is:
- [Set Environment Variables and Configurations](./deployment-values.md)
<!-- markdown-link-check-disable -->
- [Configure And Branding](./configurations/stage.ocelot.social/branding/README.md)
<!-- markdown-link-check-enable -->
### Optional: Locally Testing Configuration And Branding
@ -71,7 +75,7 @@ For the maintenance page have a look in your browser at `http://localhost:5000/`
### Push Changes To GitHub
Before merging these changes into the "master" branch on your GitHub fork repository, you need to configure the GitHub repository secrets. This is necessary to [publish](/.github/workflows/publish.yml) the Docker images by pushing them via GitHub actions to repositories belonging to your DockerHub organisation.
Before merging these changes into the "master" branch on your GitHub fork repository, you need to configure the GitHub repository secrets. This is necessary to [publish](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/.github/workflows/publish.yml) the Docker images by pushing them via GitHub actions to repositories belonging to your DockerHub organisation.
First, go to your DockerHub profile under `Account Settings` and click on the `Security` tab. There you create an access token called `<your-organisation>-access-token` and copy the token to a safe place.
@ -100,9 +104,9 @@ See the login details and browser addresses above.
### Deployment
Afterwards you can [deploy](/deployment/deployment.md) it on your server:
Afterwards you can [deploy](./deployment.md) it on your server:
- [Kubernetes with Helm](/deployment/kubernetes/README.md)
- [Kubernetes with Helm](./src/kubernetes/README.md)
## Developer Chat
@ -131,7 +135,7 @@ Browser compatibility testing with [BrowserStack](https://www.browserstack.com/)
## License
See the [LICENSE](/LICENSE.md) file for license rights and limitations (MIT).
See the [LICENSE](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/LICENSE.md) file for license rights and limitations (MIT).
We need `DOCKER_BUILDKIT=0` for this to work.

View File

@ -4,7 +4,7 @@ When you introduce a new version and branding and deploy it on your network, you
## Version >= 3.3.0 with 'ocelotDockerVersionTag' 3.3.0-XXX
- We have the new option to configure DKIM for sent e-mails in environment variables (`.env` or `values.yaml`), see [here](deployment.md):
- We have the new option to configure DKIM for sent e-mails in environment variables (`.env` or `values.yaml`), see [deployment-values.md](deployment-values.md):
- `SMTP_DKIM_DOMAINNAME=`
- `SMTP_DKIM_KEYSELECTOR=`
- `SMTP_DKIM_PRIVATKEY=`

@ -1 +1 @@
Subproject commit fdc2e52fa444b300e1c4736600bc0e9ae3314222
Subproject commit a930f11d8f2d0c11136ff0bf9188aaab9cabc5d1

View File

@ -4,14 +4,14 @@ Before you start the deployment you have to do preparations.
## Deployment Preparations
Since all deployment methods described here depend on [Docker](https://docker.com) and [DockerHub](https://hub.docker.com), you need to create your own organisation on DockerHub and put its name in the [package.json](/package.json) file as your `dockerOrganisation`.
Read more details in the [main README](/README.md) under [Usage](/README.md#usage).
Since all deployment methods described here depend on [Docker](https://docker.com) and [DockerHub](https://hub.docker.com), you need to create your own organisation on DockerHub and put its name in the [package.json](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/package.json) file as your `dockerOrganisation`.
Read more details in the [main README](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/README.md) under [Usage](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/README.md#usage).
## Deployment Methods
You have the following options for a deployment:
- [Kubernetes with Helm](./kubernetes/README.md)
- [Kubernetes with Helm](./src/kubernetes/README.md)
## After Deployment

View File

@ -142,19 +142,35 @@ services:
- 3001:80
neo4j:
# Neo4j v3.5.14-community
# image: wollehuss/neo4j-community-branded:latest
# Neo4j 4.4-community
image: ocelotsocialnetwork/neo4j-community:latest
container_name: neo4j-branded
networks:
- test-network
ports:
- 7687:7687
# only for development
# - 7474:7474
- 7474:7474
volumes:
- neo4j_data:/data
environment:
# settings reference: https://neo4j.com/docs/operations-manual/4.4/docker/ref-settings/
# TODO: This sounds scary for a production environment
- NEO4J_AUTH=none
- NEO4J_dbms_security_procedures_unrestricted=algo.*,apoc.*
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
ports:
- 7687:7687
- 7474:7474
- NEO4J_dbms_allow__format__migration=true
- NEO4J_dbms_allow__upgrade=true
# TODO: clarify if that is the only thing needed to unlock the Enterprise version
# - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
# Uncomment following line for Neo4j Enterprise version instead of Community version
# TODO: clarify if that is the only thing needed to unlock the Enterprise version
# - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
# TODO: Remove the playground from production
# bring the database in offline mode to export or load dumps
# command: ["tail", "-f", "/dev/null"]
mailserver:
image: djfarrelly/maildev

View File

@ -18,21 +18,13 @@ BACKUP_FOLDER=${BACKUP_FOLDER:-${SCRIPT_DIR}/../configurations/${CONFIGURATION}/
# create backup fodler
mkdir -p ${BACKUP_FOLDER}
# maintenance mode on
${SCRIPT_DIR}/cluster.maintenance.sh on
# shutdown database
kubectl --kubeconfig=${KUBECONFIG} get deployment ocelot-neo4j -o json \
| jq '.spec.template.spec.containers[] += {"command": ["tail", "-f", "/dev/null"]}' \
| kubectl --kubeconfig=${KUBECONFIG} apply -f -
# wait for the container to restart
sleep 60
# cluster maintenance mode on && Neo4j maintenance mode on
${SCRIPT_DIR}/cluster.neo4j.sh maintenance on
# database backup
kubectl --kubeconfig=${KUBECONFIG} -n default exec -it \
$(kubectl --kubeconfig=${KUBECONFIG} -n default get pods | grep ocelot-neo4j | awk '{ print $1 }') \
-- neo4j-admin dump --to=/var/lib/neo4j/$BACKUP_DATE-neo4j-dump
-- neo4j-admin dump --database=graph.db --to=/var/lib/neo4j/$BACKUP_DATE-neo4j-dump
# copy neo4j backup to local drive
kubectl --kubeconfig=${KUBECONFIG} cp \
default/$(kubectl --kubeconfig=${KUBECONFIG} -n default get pods | grep ocelot-neo4j |awk '{ print $1 }'):/var/lib/neo4j/$BACKUP_DATE-neo4j-dump $BACKUP_FOLDER/neo4j-dump
@ -40,13 +32,5 @@ kubectl --kubeconfig=${KUBECONFIG} cp \
kubectl --kubeconfig=${KUBECONFIG} cp \
default/$(kubectl --kubeconfig=${KUBECONFIG} -n default get pods | grep ocelot-backend |awk '{ print $1 }'):/app/public/uploads $BACKUP_FOLDER/public-uploads
# restart database
kubectl --kubeconfig=${KUBECONFIG} get deployment ocelot-neo4j -o json \
| jq 'del(.spec.template.spec.containers[].command)' \
| kubectl --kubeconfig=${KUBECONFIG} apply -f -
# wait for the container to restart
sleep 60
# maintenance mode off
${SCRIPT_DIR}/cluster.maintenance.sh off
# Neo4j maintenance mode off && cluster maintenance mode off
${SCRIPT_DIR}/cluster.neo4j.sh maintenance off

View File

@ -0,0 +1,56 @@
#!/bin/bash
# base setup
SCRIPT_PATH=$(realpath $0)
SCRIPT_DIR=$(dirname $SCRIPT_PATH)
# check CONFIGURATION
if [ -z ${CONFIGURATION} ]; then
echo "You must provide a `CONFIGURATION` via environment variable"
exit 1
fi
echo "Using CONFIGURATION=${CONFIGURATION}"
# configuration
KUBECONFIG=${KUBECONFIG:-${SCRIPT_DIR}/../configurations/${CONFIGURATION}/kubeconfig.yaml}
VALUES=${SCRIPT_DIR}/../configurations/${CONFIGURATION}/kubernetes/values.yaml
DOCKERHUB_OCELOT_TAG=${DOCKERHUB_OCELOT_TAG:-"latest"}
## install Ingress-Nginx
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install \
ingress-nginx ingress-nginx/ingress-nginx \
--kubeconfig=${KUBECONFIG} \
-f ${SCRIPT_DIR}/../src/kubernetes/nginx.values.yaml
## install Cert-Manager
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install \
cert-manager jetstack/cert-manager \
--kubeconfig=${KUBECONFIG} \
--namespace cert-manager \
--create-namespace \
--version v1.13.2 \
--set installCRDs=true
## install Ocelot with helm
helm install \
ocelot \
--kubeconfig=${KUBECONFIG} \
--values ${VALUES} \
--set appVersion="${DOCKERHUB_OCELOT_TAG}" \
${SCRIPT_DIR}/../src/kubernetes/ \
--timeout 10m
## set Neo4j database indexes, constrains, and initial admin account plus run migrate up
kubectl --kubeconfig=${KUBECONFIG} \
-n default \
exec -it \
$(kubectl --kubeconfig=${KUBECONFIG} -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- \
/bin/sh -c "yarn prod:migrate init && yarn prod:migrate up"
# /bin/sh -c "node --experimental-repl-await build/src/db/clean.js && node --experimental-repl-await build/src/db/seed.js"
echo "!!! You must install a firewall or similar !!! (for DigitalOcean see: deployment/src/kubernetes/README.md)"

View File

@ -0,0 +1,53 @@
#!/bin/bash
# base setup
SCRIPT_PATH=$(realpath $0)
SCRIPT_DIR=$(dirname $SCRIPT_PATH)
# check CONFIGURATION
if [ -z ${CONFIGURATION} ]; then
echo "You must provide a `CONFIGURATION` via environment variable"
exit 1
fi
# configuration
KUBECONFIG=${KUBECONFIG:-${SCRIPT_DIR}/../configurations/${CONFIGURATION}/kubeconfig.yaml}
case $1 in
maintenance)
case $2 in
on)
# maintenance mode on
${SCRIPT_DIR}/cluster.maintenance.sh on
# set Neo4j in offline mode (maintenance)
kubectl --kubeconfig=${KUBECONFIG} get deployment ocelot-neo4j -o json \
| jq '.spec.template.spec.containers[] += {"command": ["tail", "-f", "/dev/null"]}' \
| kubectl --kubeconfig=${KUBECONFIG} apply -f -
# wait for the container to restart
sleep 60
;;
off)
# set Neo4j in online mode
kubectl --kubeconfig=${KUBECONFIG} get deployment ocelot-neo4j -o json \
| jq 'del(.spec.template.spec.containers[].command)' \
| kubectl --kubeconfig=${KUBECONFIG} apply -f -
# wait for the container to restart
sleep 60
# maintenance mode off
${SCRIPT_DIR}/cluster.maintenance.sh off
;;
*)
echo -e "Run this script with first argument either 'off' or 'on'"
exit
;;
esac
;;
*)
echo -e "Run this script with first argument 'maintenance'"
exit
;;
esac

View File

@ -137,7 +137,7 @@ $ kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-neo4j
# bash: enter bash of Neo4j
$ kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-neo4j | awk '{ print $1 }') -- bash
# generate Dump
neo4j% neo4j-admin dump --to=/var/lib/neo4j/$(date +%F)-neo4j-dump
neo4j% neo4j-admin dump --database=graph.db --to=/var/lib/neo4j/$(date +%F)-neo4j-dump
# exit bash
neo4j% exit

View File

@ -68,17 +68,17 @@ Take one of the IPs of perhaps two or more droplets in your cluster from the lis
To understand what makes sense to do when managing your DNS with DigitalOcean, you need to know how DNS works:
DNS means `Domain Name System`. It resolves domains like `example.com` into an IP like `123.123.123.123`.
DigitalOcean is not a domain registrar, but provides a DNS management service. If you use DigitalOcean's DNS management service, you can configure [your cluster](/deployment/kubernetes/README.md#dns) to always resolve the domain to the correct IP and automatically update it for that.
DigitalOcean is not a domain registrar, but provides a DNS management service. If you use DigitalOcean's DNS management service, you can configure [your cluster](./README.md#dns) to always resolve the domain to the correct IP and automatically update it for that.
The IPs of the DigitalOcean machines are not necessarily stable, so the cluster's DNS service will update the DNS records managed by DigitalOcean to the new IP as needed.
***CAUTION:** If you are using an external DNS, you currently have to do this manually, which can cause downtime.*
## Deploy
Yeah, you're done here. Back to [Deployment with Helm for Kubernetes](/deployment/kubernetes/README.md).
Yeah, you're done here. Back to [Deployment with Helm for Kubernetes](./README.md).
## Backups On DigitalOcean
You can and should do [backups](/deployment/kubernetes/Backup.md) with Kubernetes for sure.
You can and should do [backups](./Backup.md) with Kubernetes for sure.
Additional to backup and copying the Neo4j database dump and the backend images you can do a volume snapshot on DigitalOcean at the moment you have the database in sleep mode.

View File

@ -9,7 +9,7 @@ Please contact us if you are interested in options not listed below.
Managed Kubernetes:
- [DigitalOcean](/deployment/kubernetes/DigitalOcean.md)
- [DigitalOcean](./DigitalOcean.md)
## Configuration
@ -46,29 +46,20 @@ Please have a look here:
- [Installing with Helm](https://cert-manager.io/docs/installation/helm/#installing-with-helm)
Our Helm installation is optimized for cert-manager version `v1.9.1` and `kubectl` version `"v1.24.2`.
Our Helm installation is optimized for cert-manager version `v1.13.1` and `kubectl` version `"v1.28.2`.
Please search here for cert-manager versions that are compatible with your `kubectl` version on the cluster and on the client: [cert-manager Supported Releases](https://cert-manager.io/docs/installation/supported-releases/#supported-releases).
***ATTENTION:*** *When uninstalling cert-manager, be sure to use the same method as for installation! Otherwise, we could end up in a broken state, see [Uninstall](https://cert-manager.io/docs/installation/kubectl/#uninstalling).*
<!-- #### 1. Create Namespace
```bash
# kubeconfig.yaml set globaly
$ kubectl create namespace cert-manager
# or kubeconfig.yaml in your repo, then adjust
$ kubectl --kubeconfig=/../kubeconfig.yaml create namespace cert-manager
```
#### 2. Add Helm repository and update
<!-- #### 1. Add Helm repository and update
```bash
$ helm repo add jetstack https://charts.jetstack.io
$ helm repo update
```
#### 3. Install Cert-Manager Helm chart
#### 2. Install Cert-Manager Helm chart
```bash
# option 1
@ -76,16 +67,24 @@ $ helm repo update
# $ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.3.1/cert-manager.crds.yaml
# option 2
# !!! untested for now for new deployment structure !!!
# in configuration/<deployment-name>
# kubeconfig.yaml set globaly
$ helm install cert-manager jetstack/cert-manager \
$ helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version v1.9.1 \
--create-namespace \
--version v1.13.2 \
--set installCRDs=true
# or kubeconfig.yaml in your repo, then adjust
$ helm --kubeconfig=/../kubeconfig.yaml \
install cert-manager jetstack/cert-manager \
$ helm install \
cert-manager jetstack/cert-manager \
--kubeconfig ./kubeconfig.yaml \
--namespace cert-manager \
--version v1.9.1 \
--create-namespace \
--version v1.13.2 \
--set installCRDs=true
``` -->
@ -101,10 +100,15 @@ $ helm repo update
#### 2. Install ingress-nginx
```bash
# in configuration/<deployment-name>
# kubeconfig.yaml set globaly
$ helm install ingress-nginx ingress-nginx/ingress-nginx -f nginx.values.yaml
helm install ingress-nginx ingress-nginx/ingress-nginx -f ../../src/kubernetes/nginx.values.yaml
# or kubeconfig.yaml in your repo, then adjust
$ helm --kubeconfig=/../kubeconfig.yaml install ingress-nginx ingress-nginx/ingress-nginx -f nginx.values.yaml
helm install \
ingress-nginx ingress-nginx/ingress-nginx -f ../../src/kubernetes/nginx.values.yaml \
--kubeconfig ./kubeconfig.yaml
```
### DigitalOcean Firewall
@ -159,7 +163,9 @@ $ doctl compute firewall get <ID> --context <context-name>
### DNS
***TODO:** I thought this is necessary if we use the DigitalOcean DNS management service? See [Manage DNS With DigitalOcean](/deployment/kubernetes/DigitalOcean.md#manage-dns-with-digitalocean)*
***ATTENTION:** This seems not to work at all so we leave it away at the moment*
***TODO:** I thought this is necessary if we use the DigitalOcean DNS management service? See [Manage DNS With DigitalOcean](./DigitalOcean.md#manage-dns-with-digitalocean)*
This chart is only necessary (recommended is more precise) if you run DigitalOcean without load balancer.
You need to generate an access token with read + write for the `dns.values.yaml` at <https://cloud.digitalocean.com/account/api/tokens> and fill it in.
@ -174,6 +180,8 @@ $ helm repo update
#### 2. Install DNS
```bash
# !!! untested for now for new deployment structure !!!
# kubeconfig.yaml set globaly
$ helm install dns bitnami/external-dns -f dns.values.yaml
# or kubeconfig.yaml in your repo, then adjust
@ -191,10 +199,22 @@ All commands for ocelot need to be executed in the kubernetes folder. Therefore
Only run once for the first time of installation:
```bash
# in configuration/<deployment-name>
# kubeconfig.yaml set globaly
$ helm install ocelot ./
helm install ocelot \
--values ./kubernetes/values.yaml \
--set appVersion="latest" \
../../src/kubernetes/ \
--timeout 10m
# or kubeconfig.yaml in your repo, then adjust
$ helm --kubeconfig=/../kubeconfig.yaml install ocelot ./
helm install ocelot \
--kubeconfig ./kubeconfig.yaml \
--values ./kubernetes/values.yaml \
--set appVersion="latest" \
../../src/kubernetes/ \
--timeout 10m
```
#### Upgrade & Update
@ -202,10 +222,24 @@ $ helm --kubeconfig=/../kubeconfig.yaml install ocelot ./
Run for all upgrades and updates:
```bash
# !!! untested for now for new deployment structure !!!
# in configuration/<deployment-name>
# kubeconfig.yaml set globaly
$ helm upgrade ocelot ./
helm upgrade ocelot \
--values ./kubernetes/values.yaml \
--set appVersion="latest" \
../../src/kubernetes/ \
--timeout 10m
# or kubeconfig.yaml in your repo, then adjust
$ helm --kubeconfig=/../kubeconfig.yaml upgrade ocelot ./
helm upgrade ocelot \
--kubeconfig ./kubeconfig.yaml \
--values ./kubernetes/values.yaml \
--set appVersion="latest" \
../../src/kubernetes/ \
--timeout 10m
```
#### Rollback
@ -213,10 +247,17 @@ $ helm --kubeconfig=/../kubeconfig.yaml upgrade ocelot ./
Run for a rollback, in case something went wrong:
```bash
# !!! untested for now for new deployment structure !!!
# in configuration/<deployment-name>
# kubeconfig.yaml set globaly
$ helm rollback ocelot
helm rollback ocelot --timeout 10m
# or kubeconfig.yaml in your repo, then adjust
$ helm --kubeconfig=/../kubeconfig.yaml rollback ocelot
helm rollback ocelot \
--kubeconfig ./kubeconfig.yaml \
--timeout 10m
```
#### Uninstall
@ -224,17 +265,24 @@ $ helm --kubeconfig=/../kubeconfig.yaml rollback ocelot
Be aware that if you uninstall ocelot the formerly bound volumes become unbound. Those volumes contain all data from uploads and database. You have to manually free their reference in order to bind them again when reinstalling. Once unbound from their former container references they should automatically be rebound (considering the sizes did not change)
```bash
# !!! untested for now for new deployment structure !!!
# in configuration/<deployment-name>
# kubeconfig.yaml set globaly
$ helm uninstall ocelot
helm uninstall ocelot --timeout 10m
# or kubeconfig.yaml in your repo, then adjust
$ helm --kubeconfig=/../kubeconfig.yaml uninstall ocelot
helm uninstall ocelot \
--kubeconfig ./kubeconfig.yaml \
--timeout 10m
```
## Backups
You can and should do [backups](/deployment/kubernetes/Backup.md) with Kubernetes for sure.
You can and should do [backups](./Backup.md) with Kubernetes for sure.
## Error Reporting
<!-- ## Error Reporting
We use [Sentry](https://github.com/getsentry/sentry) for error reporting in both
our backend and web frontend. You can either use a hosted or a self-hosted
@ -249,7 +297,7 @@ If you are lucky enough to have a kubernetes cluster with the required hardware
support, try this [helm chart](https://github.com/helm/charts/tree/master/stable/sentry).
On our kubernetes cluster we get "mult-attach" errors for persistent volumes.
Apparently DigitalOcean's kubernetes clusters do not fulfill the requirements.
Apparently DigitalOcean's kubernetes clusters do not fulfill the requirements. -->
## Kubernetes Commands (Without Helm) To Deploy New Docker Images To A Kubernetes Cluster
@ -292,8 +340,11 @@ $ kubectl -n default rollout status deployment/ocelot-neo4j --timeout=240s
# !!! be aware of the correct kube context !!!
$ kubectl config get-contexts
# reset and seed Neo4j database via backend for staging
# for staging: reset and seed Neo4j database via backend
$ kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- /bin/sh -c "node --experimental-repl-await build/src/db/clean.js && node --experimental-repl-await build/src/db/seed.js"
# or alternatively
# for production: set Neo4j database indexes, constrains, and initial admin account plus run migrate up via backend
$ kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- /bin/sh -c "yarn prod:migrate init && yarn prod:migrate up"
```

View File

@ -21,6 +21,8 @@ data:
SMTP_PORT: "{{ .Values.BACKEND.SMTP_PORT }}"
SMTP_IGNORE_TLS: "{{ .Values.BACKEND.SMTP_IGNORE_TLS }}"
SMTP_SECURE: "{{ .Values.BACKEND.SMTP_SECURE }}"
SMTP_DKIM_DOMAINNAME: "{{ .Values.BACKEND.SMTP_DKIM_DOMAINNAME }}"
SMTP_DKIM_KEYSELECTOR: "{{ .Values.BACKEND.SMTP_DKIM_KEYSELECTOR }}"
GRAPHQL_URI: "http://{{ .Release.Name }}-backend:4000"
NEO4J_URI: "bolt://{{ .Release.Name }}-neo4j:7687"
#REDIS_DOMAIN: ---toBeSet(IP)---

View File

@ -16,6 +16,7 @@ stringData:
PRIVATE_KEY_PASSPHRASE: "{{ .Values.BACKEND.PRIVATE_KEY_PASSPHRASE }}"
SMTP_USERNAME: "{{ .Values.BACKEND.SMTP_USERNAME }}"
SMTP_PASSWORD: "{{ .Values.BACKEND.SMTP_PASSWORD }}"
SMTP_DKIM_PRIVATKEY: "{{ .Values.BACKEND.SMTP_DKIM_PRIVATKEY }}"
#NEO4J_USERNAME: ""
#NEO4J_PASSWORD: ""
#REDIS_PASSWORD: ---toBeSet---

View File

@ -23,13 +23,12 @@ CAUTION: It seems that the behaviour of DigitalOcean has changed and the load ba
And to create a load balancer costs money. Please refine the following documentation if required.
{% endhint %}
{% tabs %}
{% tab title="Without Load Balancer" %}
::: tabs
@tab:active Without Load Balancer
A solution without a load balance you can find [here](../no-loadbalancer/README.md).
{% endtab %}
{% tab title="With DigitalOcean Load Balancer" %}
@tab With DigitalOcean Load Balancer
{% hint style="info" %}
CAUTION: It seems that the behaviour of DigitalOcean has changed and the load balancer is not created automatically anymore.
@ -44,8 +43,7 @@ address. On DigitalOcean, this is how it should look like:
If the load balancer isn't created automatically you have to create it your self on DigitalOcean under Networks.
In case you don't need a DigitalOcean load balancer (which costs money by the way) have a look in the tab `Without Load Balancer`.
{% endtab %}
{% endtabs %}
:::
Check the ingress server is working correctly:

View File

@ -108,6 +108,7 @@ services:
volumes:
- neo4j_data:/data
environment:
# settings reference: https://neo4j.com/docs/operations-manual/4.4/docker/ref-settings/
# TODO: This sounds scary for a production environment
- NEO4J_AUTH=none
- NEO4J_dbms_security_procedures_unrestricted=algo.*,apoc.*
@ -117,6 +118,8 @@ services:
# TODO: clarify if that is the only thing needed to unlock the Enterprise version
# - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
# TODO: Remove the playground from production
# bring the database in offline mode to export or load dumps
# command: ["tail", "-f", "/dev/null"]
networks:
external-net:

View File

@ -1,46 +1,46 @@
# Edit this Documentation
# Documentation
## Edit this Documentation
Find the [**table of contents** for this documentation on GitHub](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/SUMMARY.md) and navigate to the file you need to update.
Click on the **edit pencil** on the right side directly above the text to edit this file on your fork of Human Connection \(HC\).
Click on the **edit pencil** on the right side directly above the text to edit this file in our repository.
You can see a preview of your changes by clicking the **Preview changes** tab aside the **Edit file** tab.
If you are ready, fill in the **Propose file change** at the end of the webpage.
After that you have to send your change to the HC basis with a pull request. Here make a comment which issue you have fixed. (If you are working on one of our [open issues](https://github.com/Ocelot-Social-Community/Ocelot-Social/issues) please include the number.)
After that you have to compare your change branch to our `master` branch with a pull request. Here make a comment which issue you have fixed. (If you are working on one of our [open issues](https://github.com/Ocelot-Social-Community/Ocelot-Social/issues) please include the number.)
## Markdown your documentation
### Markdown your documentation
To design your documentation see the syntax description at GitBook:
[https://toolchain.gitbook.com/syntax/markdown.html](https://toolchain.gitbook.com/syntax/markdown.html)
### Some quick Examples
#### Some quick Examples
#### Headlines
##### Headlines
```markdown
# Main headline
## Smaller headlines
### Small headlines
# Main Headline
## Smaller Headlines
### Small Headlines
```
#### Tabs
##### Tabs
```markdown
{% tabs %}
{% tab title="XXX" %}
XXX
{% endtab %}
{% tab title="XXX" %}
XXX
{% endtab %}
{% endtabs %}
::: tabs
@tab:active First tab's title <!-- this tab is setactive -->
@tab Second tab's title
:::
```
#### Commands
##### Commands
~~~markdown
```<LANGUAGE> (for text highlighting)
@ -48,33 +48,34 @@ XXX
```
~~~
#### Links
##### Links
```markdown
[XXX](https://XXX)
```
For the documentation to work in both frameworks - Github and Vuepress - please use absolute path for Github internal documentation links (e.g. /README.md over ../../README.mdetc.)
#### Screenshots or other Images
##### Screenshots or other Images
```markdown
![XXX](https://XXX)
```
#### Hints For ToDos
##### Hints for ToDos
```markdown
{% hint style="info" %} TODO: XXX {% endhint %}
```
## Host The Screenshots
### Host the Screenshots
### Host On Ocelot-Social \(GitHub\) repository
#### Host on Ocelot-Social \(GitHub\) Repository
{% hint style="info" %}
TODO: How to host on Ocelot-Social \(GitHub\) repository ...
{% endhint %}
### Quick Solution
#### Quick Solution
To quickly host the screenshots go to:
@ -88,26 +89,41 @@ Right click on it and choose kind of **Open link in new tab**.
Copy the URL and paste it were you need it.
## Screenshot modification
### Screenshot Modification
### Add an arrow or some other marking stuff
#### Add an Arrow or some other Marking Stuff
{% tabs %}
{% tab title="macOS" %}
#### In the Preview App
::: tabs
@tab:active macOS
##### In the Preview App
Got to: **Menu** + **Tools** \(GER: Werkzeuge\) + **Annotate** \(GER: Anmerkungen\) + etc.
{% endtab %}
{% tab title="Windows" %}
@tab Windows
{% hint style="info" %}
TODO: How to modify screenshots in Windows ...
{% endhint %}
{% endtab %}
{% tab title="Linux" %}
@tab Linux
{% hint style="info" %}
TODO: How to modify screenshots in Linux ...
{% endhint %}
{% endtab %}
{% endtabs %}
:::
## Deploy this Documentation
TODO
```bash
# set configured Node version
nvm use
# install Vuepress
npm install
# run vuepress
npm run docs:dev
```

View File

@ -16,11 +16,11 @@ ENV BUILD_COMMIT=$BBUILD_COMMIT
# Labels
LABEL org.label-schema.build-date="${BUILD_DATE}"
LABEL org.label-schema.name="ocelot.social:backend"
LABEL org.label-schema.name="ocelot.social:neo4j"
LABEL org.label-schema.description="Neo4J database of the Social Network Software ocelot.social with preinstalled database constraints and indices"
LABEL org.label-schema.usage="https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/README.md"
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-url="https://github.com/Ocelot-Social-Community/Ocelot-Social/tree/master/neo4j"
LABEL org.label-schema.vcs-ref="${BUILD_COMMIT}"
LABEL org.label-schema.vendor="ocelot.social Community"
LABEL org.label-schema.version="${BUILD_VERSION}"

View File

@ -51,6 +51,48 @@ in `backend/.env`.
Start Neo4J and confirm the database is running at [http://localhost:7474](http://localhost:7474).
## Operations on Neo4j
### Docker or Docker Compose
- we need to set `command: ["tail", "-f", "/dev/null"]` in the Neo4j block of `docker-compose.yml` on top level so the Neo4j database is in maintenance mode
### Create Neo4j Dump
To create a dump in Neo4j running in a Docker container:
- set the database to maintenance mode, see above
- entering the following commands:
```bash
# connect to the Docker containers Neo4j terminal
$ docker exec -it neo4j bash
# generate Dump
neo4j% neo4j-admin dump --database=graph.db --to=/var/lib/neo4j/$(date +%F)-neo4j-dump
# exit bash
neo4j% exit
# copy the dump out of the running Docker container
$ docker cp <docker-image-name('neo4j')>:/var/lib/neo4j/neo4j-dump <local-folder-path>/$(date +%F)-neo4j-dump
```
### Import Neo4j Dump
To import a dump into Neo4j running in a Docker container:
- set the database to maintenance mode, see above
- entering the following commands:
```bash
# copy the dump into the running Docker container
$ docker cp <local-folder-path>/neo4j-dump <docker-image-name('neo4j')>:/var/lib/neo4j/$(date +%F)-neo4j-dump
# connect to the Docker containers Neo4j terminal
$ docker exec -it neo4j bash
# to load the dump into the database we need the following command in this terminal
neo4j% neo4j-admin load --database=neo4j --from /var/lib/neo4j/$(date +%F)-neo4j-dump --force
# leave the terminal by entering
neo4j% exit
```
## Commands
Here we describe some rarely used Cypher commands for Neo4j that are needed from time to time:

16248
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,9 @@
{
"name": "ocelot-social",
"version": "3.0.3",
"version": "3.1.2",
"description": "Free and open source software program code available to run social networks.",
"author": "ocelot.social Community",
"license": "MIT",
"private": false,
"repository": {
"type": "git",
"url": "https://github.com/Ocelot-Social-Community/Ocelot-Social.git"
@ -27,38 +26,43 @@
"scripts": {
"db:seed": "cd backend && yarn run db:seed",
"db:reset": "cd backend && yarn run db:reset",
"docs:build": "NODE_OPTIONS=--openssl-legacy-provider vuepress build .",
"docs:dev": "NODE_OPTIONS=--openssl-legacy-provider vuepress dev .",
"cypress:run": "cypress run --e2e --browser electron --config-file ./cypress/cypress.config.js",
"cypress:open": "cypress open --e2e --browser electron --config-file ./cypress/cypress.config.js",
"cucumber:setup": "cd backend && yarn run dev",
"cucumber": "wait-on tcp:4000 && cucumber-js --require-module @babel/register --exit",
"release": "yarn version --no-git-tag-version --no-commit-hooks --no-commit && auto-changelog --latest-version $(node -p -e \"require('./package.json').version\") && cd backend && yarn version --no-git-tag-version --no-commit-hooks --no-commit --new-version $(node -p -e \"require('./../package.json').version\") && cd ../webapp && yarn version --no-git-tag-version --no-commit-hooks --no-commit --new-version $(node -p -e \"require('./../package.json').version\") && cd ../webapp/maintenance/source && yarn version --no-git-tag-version --no-commit-hooks --no-commit --new-version $(node -p -e \"require('./../../../package.json').version\")"
},
"devDependencies": {
"@babel/core": "^7.22.9",
"@babel/preset-env": "^7.22.9",
"@babel/register": "^7.12.10",
"@badeball/cypress-cucumber-preprocessor": "^15.1.4",
"@babel/core": "^7.23.5",
"@babel/preset-env": "^7.23.5",
"@babel/register": "^7.22.15",
"@badeball/cypress-cucumber-preprocessor": "^19.2.0",
"@cypress/browserify-preprocessor": "^3.0.2",
"@faker-js/faker": "8.0.2",
"@cucumber/cucumber": "10.0.1",
"@faker-js/faker": "8.3.1",
"auto-changelog": "^2.3.0",
"bcryptjs": "^2.4.3",
"cross-env": "^7.0.3",
"cucumber": "^6.0.5",
"cypress": "^12.17.0",
"cypress": "^13.6.1",
"cypress-network-idle": "^1.14.2",
"date-fns": "^2.25.0",
"dotenv": "^16.3.1",
"expect": "^29.5.0",
"expect": "^29.6.4",
"graphql-request": "^2.0.0",
"import": "^0.0.6",
"jsonwebtoken": "^8.5.1",
"jsonwebtoken": "^9.0.2",
"mock-socket": "^9.0.3",
"multiple-cucumber-html-reporter": "^3.4.0",
"neo4j-driver": "^4.3.4",
"neode": "^0.4.8",
"rosie": "^2.1.0",
"slug": "^6.0.0",
"wait-on": "^7.0.1"
"slug": "^8.2.3",
"wait-on": "^7.2.0"
},
"optionalDependencies": {
"vuepress": "^2.0.0-rc.0",
"vuepress-plugin-search-pro": "^2.0.0-rc.4",
"vuepress-theme-hope": "^2.0.0-rc.4"
},
"resolutions": {
"set-value": "^2.0.1",

View File

@ -22,11 +22,11 @@ ENV PORT="3000"
# Labels
LABEL org.label-schema.build-date="${BUILD_DATE}"
LABEL org.label-schema.name="ocelot.social:backend"
LABEL org.label-schema.name="ocelot.social:webapp"
LABEL org.label-schema.description="Web Frontend of the Social Network Software ocelot.social"
LABEL org.label-schema.usage="https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/README.md"
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-url="https://github.com/Ocelot-Social-Community/Ocelot-Social/tree/master/webapp"
LABEL org.label-schema.vcs-ref="${BUILD_COMMIT}"
LABEL org.label-schema.vendor="ocelot.social Community"
LABEL org.label-schema.version="${BUILD_VERSION}"

View File

@ -1,7 +1,7 @@
##################################################################################
# BASE ###########################################################################
##################################################################################
FROM node:20.3.0-alpine3.17 as base
FROM node:20.2.0-alpine3.17 as base
# ENVs
## DOCKER_WORKDIR would be a classical ARG, but that is not multi layer persistent - shame
@ -22,11 +22,11 @@ ENV PORT="3000"
# Labels
LABEL org.label-schema.build-date="${BUILD_DATE}"
LABEL org.label-schema.name="ocelot.social:backend"
LABEL org.label-schema.name="ocelot.social:maintenance"
LABEL org.label-schema.description="Maintenance page of the Social Network Software ocelot.social"
LABEL org.label-schema.usage="https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/README.md"
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-url="https://github.com/Ocelot-Social-Community/Ocelot-Social/tree/master/webapp"
LABEL org.label-schema.vcs-ref="${BUILD_COMMIT}"
LABEL org.label-schema.vendor="ocelot.social Community"
LABEL org.label-schema.version="${BUILD_VERSION}"

View File

@ -59,8 +59,8 @@ We ensure the quality of our frontend code by using
For more information see our [frontend testing guide](testing.md). Use these commands to run the tests:
{% tabs %}
{% tab title="With Docker" %}
::: tabs
@tab:active With Docker
After starting the application following the above guidelines, open new terminal windows for each of these commands:
@ -81,9 +81,7 @@ $ docker-compose exec webapp yarn storybook
You can then visit the Storybook playground on `http://localhost:3002`
{% endtab %}
{% tab title="Without Docker" %}
@tab title Without Docker
After starting the application following the above guidelines, open new terminal windows and navigate to the `/webapp` directory for each of these commands:
@ -109,8 +107,7 @@ $ yarn storybook
You can then visit the Storybook playground on `http://localhost:3002`
{% endtab %}
{% endtabs %}
:::
## Maintenance Mode

View File

@ -328,9 +328,9 @@ export default {
eventInput() {
if (this.createEvent) {
return {
eventStart: this.formData.eventStart,
eventStart: new Date(this.formData.eventStart).toISOString(),
eventVenue: this.formData.eventVenue,
eventEnd: this.formData.eventEnd,
eventEnd: this.formData.eventEnd ? new Date(this.formData.eventEnd).toISOString() : null,
eventIsOnline: this.formData.eventIsOnline,
eventLocationName: !this.formData.eventIsOnline ? this.formData.eventLocationName : null,
}

View File

@ -46,7 +46,7 @@ describe('DonationInfo.vue', () => {
// it looks to me that toLocaleString for some reason is not working as expected
it.skip('creates a label from the given amounts and a translation string', () => {
expect(mocks.$t).nthCalledWith(1, 'donations.amount-of-total', {
expect(mocks.$t).toHaveBeenNthCalledWith(1, 'donations.amount-of-total', {
amount: '10.000',
total: '50.000',
})
@ -55,7 +55,7 @@ describe('DonationInfo.vue', () => {
describe('given english locale', () => {
it('creates a label from the given amounts and a translation string', () => {
expect(mocks.$t).toBeCalledWith(
expect(mocks.$t).toHaveBeenCalledWith(
'donations.amount-of-total',
expect.objectContaining({
amount: '10,000',

View File

@ -3,7 +3,7 @@
<div class="filter-menu-options">
<div class="filter-header">
<h2 class="title">{{ $t('filter-menu.filter-by') }}</h2>
<div class="item-save-topics">
<div v-if="categoriesActive" class="item-save-topics">
<labeled-button
filled
:label="$t('actions.saveCategories')"
@ -62,18 +62,20 @@ export default {
},
methods: {
saveCategories() {
this.$apollo
.mutate({
mutation: SaveCategories(),
variables: { activeCategories: this.filteredCategoryIds },
})
.then(() => {
this.$emit('showFilterMenu')
this.$toast.success(this.$t('filter-menu.save.success'))
})
.catch(() => {
this.$toast.error(this.$t('filter-menu.save.error'))
})
if (this.categoriesActive) {
this.$apollo
.mutate({
mutation: SaveCategories(),
variables: { activeCategories: this.filteredCategoryIds },
})
.then(() => {
this.$emit('showFilterMenu')
this.$toast.success(this.$t('filter-menu.save.success'))
})
.catch(() => {
this.$toast.error(this.$t('filter-menu.save.error'))
})
}
},
},
}

View File

@ -94,20 +94,20 @@ describe('GroupMember', () => {
describe('with server error', () => {
it('toasts an error message', () => {
expect(toastErrorMock).toBeCalledWith('Oh no!')
expect(toastErrorMock).toHaveBeenCalledWith('Oh no!')
})
})
describe('with server success', () => {
it('calls the API', () => {
expect(apolloMock).toBeCalledWith({
expect(apolloMock).toHaveBeenCalledWith({
mutation: changeGroupMemberRoleMutation(),
variables: { groupId: 'group-id', userId: 'user', roleInGroup: 'admin' },
})
})
it('toasts a success message', () => {
expect(toastSuccessMock).toBeCalledWith('group.changeMemberRole')
expect(toastSuccessMock).toHaveBeenCalledWith('group.changeMemberRole')
})
})
})
@ -150,7 +150,7 @@ describe('GroupMember', () => {
})
it('toasts an error message', () => {
expect(toastErrorMock).toBeCalledWith('Oh no!!')
expect(toastErrorMock).toHaveBeenCalledWith('Oh no!!')
})
it('closes the modal', () => {
@ -165,7 +165,7 @@ describe('GroupMember', () => {
})
it('calls the API', () => {
expect(apolloMock).toBeCalledWith({
expect(apolloMock).toHaveBeenCalledWith({
mutation: removeUserFromGroupMutation(),
variables: { groupId: 'group-id', userId: 'user' },
})
@ -176,7 +176,7 @@ describe('GroupMember', () => {
})
it('toasts a success message', () => {
expect(toastSuccessMock).toBeCalledWith('group.memberRemoved')
expect(toastSuccessMock).toHaveBeenCalledWith('group.memberRemoved')
})
it('closes the modal', () => {

View File

@ -75,8 +75,8 @@ describe('LoginForm', () => {
describe('no categories saved', () => {
it('resets the categories', async () => {
await fillIn(Wrapper())
expect(storeMocks.mutations['posts/RESET_CATEGORIES']).toBeCalled()
expect(storeMocks.mutations['posts/TOGGLE_CATEGORY']).not.toBeCalled()
expect(storeMocks.mutations['posts/RESET_CATEGORIES']).toHaveBeenCalled()
expect(storeMocks.mutations['posts/TOGGLE_CATEGORY']).not.toHaveBeenCalled()
})
})
@ -84,11 +84,11 @@ describe('LoginForm', () => {
it('sets the categories', async () => {
authUserMock.mockReturnValue({ activeCategories: ['cat1', 'cat9', 'cat12'] })
await fillIn(Wrapper())
expect(storeMocks.mutations['posts/RESET_CATEGORIES']).toBeCalled()
expect(storeMocks.mutations['posts/TOGGLE_CATEGORY']).toBeCalledTimes(3)
expect(storeMocks.mutations['posts/TOGGLE_CATEGORY']).toBeCalledWith({}, 'cat1')
expect(storeMocks.mutations['posts/TOGGLE_CATEGORY']).toBeCalledWith({}, 'cat9')
expect(storeMocks.mutations['posts/TOGGLE_CATEGORY']).toBeCalledWith({}, 'cat12')
expect(storeMocks.mutations['posts/RESET_CATEGORIES']).toHaveBeenCalled()
expect(storeMocks.mutations['posts/TOGGLE_CATEGORY']).toHaveBeenCalledTimes(3)
expect(storeMocks.mutations['posts/TOGGLE_CATEGORY']).toHaveBeenCalledWith({}, 'cat1')
expect(storeMocks.mutations['posts/TOGGLE_CATEGORY']).toHaveBeenCalledWith({}, 'cat9')
expect(storeMocks.mutations['posts/TOGGLE_CATEGORY']).toHaveBeenCalledWith({}, 'cat12')
})
})
})

View File

@ -73,7 +73,7 @@ describe('PostTeaser', () => {
it('has no validation errors', () => {
const spy = jest.spyOn(global.console, 'error')
Wrapper()
expect(spy).not.toBeCalled()
expect(spy).not.toHaveBeenCalled()
spy.mockReset()
})

View File

@ -1,7 +1,7 @@
<template>
<span class="counter-icon">
<base-icon :name="icon" />
<span :class="counterClass">{{ cappedCount }}</span>
<span v-if="count > 0" :class="counterClass">{{ cappedCount }}</span>
</span>
</template>

View File

@ -53,6 +53,16 @@ export const searchPosts = gql`
shoutedCount
clickedCount
viewedTeaserCount
postType
eventStart
eventEnd
eventVenue
eventLocationName
eventLocation {
lng
lat
}
eventIsOnline
author {
...user
}

13
webapp/jsconfig.json Normal file
View File

@ -0,0 +1,13 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~/*": [
"./*"
],
"~*": [
"./*"
],
}
}
}

View File

@ -8,8 +8,8 @@ The maintenance mode shows a translatable page that tells the user that we are r
At the moment the maintenance mode can only be locally tested with Docker-Compose.
{% tabs %}
{% tab title="Locally Without Docker" %}
::: tabs
@tab:active Locally Without Docker
{% hint style="info" %}
TODO: Implement a locally running maintenance mode! Without Docker …
@ -25,8 +25,7 @@ $ yarn generate:maintenance
… is unfortunatelly **not(!)** working at the moment.
This is because the code is rewritten to be easy usable for Docker-Compose. Therefore we lost this possibility.
{% endtab %}
{% tab title="Locally With Docker" %}
@tab Locally With Docker
To get the maintenance mode running use the command:
@ -37,3 +36,5 @@ $ docker-compose up
And the maintenance mode page or service will be started as well in an own container.
In the browser you can reach it under `http://localhost:3001/`.
:::

View File

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

View File

@ -1,6 +1,6 @@
{
"name": "ocelot-social-webapp",
"version": "3.0.3",
"version": "3.1.2",
"description": "ocelot.social Frontend",
"repository": "https://github.com/Ocelot-Social-Community/Ocelot-Social",
"author": "ocelot.social Community",
@ -32,7 +32,7 @@
"apollo-cache-inmemory": "~1.6.6",
"apollo-client": "~2.6.8",
"cookie-universal-nuxt": "~2.2.2",
"cropperjs": "^1.5.5",
"cropperjs": "^1.6.1",
"cross-env": "~7.0.3",
"date-fns": "2.22.1",
"express": "~4.17.1",
@ -75,7 +75,7 @@
"@storybook/addon-a11y": "^6.3.6",
"@storybook/addon-actions": "^5.3.21",
"@storybook/addon-notes": "^5.3.18",
"@storybook/vue": "~6.3.6",
"@storybook/vue": "~7.4.0",
"@vue/cli-shared-utils": "~4.3.1",
"@vue/eslint-config-prettier": "~6.0.0",
"@vue/server-test-utils": "~1.0.0-beta.31",

View File

@ -114,11 +114,11 @@ describe('PostIndex', () => {
})
it('resets the category filter', () => {
expect(mutations['posts/RESET_CATEGORIES']).toBeCalled()
expect(mutations['posts/RESET_CATEGORIES']).toHaveBeenCalled()
})
it('sets the category', () => {
expect(mutations['posts/TOGGLE_CATEGORY']).toBeCalledWith({}, 'cat3')
expect(mutations['posts/TOGGLE_CATEGORY']).toHaveBeenCalledWith({}, 'cat3')
})
})
})

View File

@ -19,7 +19,7 @@
</client-only>
</div>
<div>
<div v-if="categoriesActive && SHOW_CONTENT_FILTER_MASONRY_GRID" class="top-filter-menu">
<div v-if="SHOW_CONTENT_FILTER_MASONRY_GRID" class="top-filter-menu">
<div class="filterButtonBox">
<div class="filterButtonMenu" :class="{ 'hide-filter': hideByScroll }">
<base-button

View File

@ -71,7 +71,7 @@ describe('Login.vue', () => {
asyncData = true
tosVersion = '0.0.4'
wrapper = await Wrapper()
expect(redirect).toBeCalledWith('/')
expect(redirect).toHaveBeenCalledWith('/')
})
})
})

View File

@ -36,8 +36,8 @@ describe('logout.vue', () => {
})
it('logs out and redirects to login', () => {
expect(mocks.$store.dispatch).toBeCalledWith('auth/logout')
expect(mocks.$router.replace).toBeCalledWith('/login')
expect(mocks.$store.dispatch).toHaveBeenCalledWith('auth/logout')
expect(mocks.$router.replace).toHaveBeenCalledWith('/login')
})
})
})

View File

@ -114,19 +114,19 @@ describe('map', () => {
})
it('initializes on style load', () => {
expect(mapOnMock).toBeCalledWith('style.load', expect.any(Function))
expect(mapOnMock).toHaveBeenCalledWith('style.load', expect.any(Function))
})
it('initializes on mouseenter', () => {
expect(mapOnMock).toBeCalledWith('mouseenter', 'markers', expect.any(Function))
expect(mapOnMock).toHaveBeenCalledWith('mouseenter', 'markers', expect.any(Function))
})
it('initializes on mouseleave', () => {
expect(mapOnMock).toBeCalledWith('mouseleave', 'markers', expect.any(Function))
expect(mapOnMock).toHaveBeenCalledWith('mouseleave', 'markers', expect.any(Function))
})
it('calls add map control', () => {
expect(mapAddControlMock).toBeCalled()
expect(mapAddControlMock).toHaveBeenCalled()
})
describe('trigger style load event', () => {
@ -137,7 +137,7 @@ describe('map', () => {
})
it('calls loadMarkersIconsAndAddMarkers', () => {
expect(spy).toBeCalled()
expect(spy).toHaveBeenCalled()
})
})

View File

@ -68,7 +68,7 @@ describe('password-reset.vue', () => {
asyncData = true
isLoggedIn = true
wrapper = await Wrapper()
expect(redirect).toBeCalledWith('/')
expect(redirect).toHaveBeenCalledWith('/')
})
})
})

View File

@ -76,7 +76,10 @@ describe('post/_id.vue', () => {
authorId = 'some-author'
userId = 'some-user'
wrapper = await Wrapper()
expect(error).toBeCalledWith({ message: 'error-pages.cannot-edit-post', statusCode: 403 })
expect(error).toHaveBeenCalledWith({
message: 'error-pages.cannot-edit-post',
statusCode: 403,
})
})
it('renders with asyncData of same user', async () => {

View File

@ -327,7 +327,7 @@ describe('Registration', () => {
asyncData = true
isLoggedIn = true
wrapper = await Wrapper()
expect(redirect).toBeCalledWith('/')
expect(redirect).toHaveBeenCalledWith('/')
})
// copied from webapp/components/Registration/Signup.spec.js as testing template

View File

@ -71,7 +71,7 @@ describe('terms-and-conditions-confirm.vue', () => {
asyncData = true
tosAgree = true
wrapper = await Wrapper()
expect(redirect).toBeCalledWith('/')
expect(redirect).toHaveBeenCalledWith('/')
})
})
})

File diff suppressed because it is too large Load Diff

6010
yarn.lock

File diff suppressed because it is too large Load Diff