Compare commits
No commits in common. "a400c7210c88b4c6ced529deab9d8366a434b245" and "16438014fad9929d893427f5cb7161ac38917d4e" have entirely different histories.
a400c7210c
...
16438014fa
|
@ -1,5 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
extends: [
|
|
||||||
'@nextcloud',
|
|
||||||
]
|
|
||||||
}
|
|
3
.gitattributes
vendored
3
.gitattributes
vendored
|
@ -1,3 +0,0 @@
|
||||||
/js/* binary
|
|
||||||
*.png -text
|
|
||||||
*.epgz -text
|
|
24
.github/dependabot.yml
vendored
24
.github/dependabot.yml
vendored
|
@ -1,24 +0,0 @@
|
||||||
version: 2
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: composer
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: weekly
|
|
||||||
day: saturday
|
|
||||||
time: "03:00"
|
|
||||||
timezone: Europe/Paris
|
|
||||||
open-pull-requests-limit: 10
|
|
||||||
labels:
|
|
||||||
- 3. to review
|
|
||||||
- dependencies
|
|
||||||
- package-ecosystem: npm
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: weekly
|
|
||||||
day: saturday
|
|
||||||
time: "03:00"
|
|
||||||
timezone: Europe/Paris
|
|
||||||
open-pull-requests-limit: 10
|
|
||||||
labels:
|
|
||||||
- 3. to review
|
|
||||||
- dependencies
|
|
117
.github/workflows/command-compile.yml
vendored
117
.github/workflows/command-compile.yml
vendored
|
@ -1,117 +0,0 @@
|
||||||
name: Compile Command
|
|
||||||
on:
|
|
||||||
issue_comment:
|
|
||||||
types: [created]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
init:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
# On pull requests and if the comment starts with `/compile`
|
|
||||||
if: github.event.issue.pull_request != '' && startsWith(github.event.comment.body, '/compile')
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
git_path: ${{ steps.git-path.outputs.path }}
|
|
||||||
arg1: ${{ steps.command.outputs.arg1 }}
|
|
||||||
arg2: ${{ steps.command.outputs.arg2 }}
|
|
||||||
head_ref: ${{ steps.comment-branch.outputs.head_ref }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Check actor permission
|
|
||||||
uses: skjnldsv/check-actor-permission@v2
|
|
||||||
with:
|
|
||||||
require: write
|
|
||||||
|
|
||||||
- name: Add reaction on start
|
|
||||||
uses: peter-evans/create-or-update-comment@v1
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
|
||||||
repository: ${{ github.event.repository.full_name }}
|
|
||||||
comment-id: ${{ github.event.comment.id }}
|
|
||||||
reaction-type: "+1"
|
|
||||||
|
|
||||||
- name: Parse command
|
|
||||||
uses: skjnldsv/parse-command-comment@master
|
|
||||||
id: command
|
|
||||||
|
|
||||||
# Init path depending on which command is run
|
|
||||||
- name: Init path
|
|
||||||
id: git-path
|
|
||||||
run: |
|
|
||||||
if ${{ startsWith(steps.command.outputs.arg1, '/') }}; then
|
|
||||||
echo "::set-output name=path::${{ github.workspace }}${{steps.command.outputs.arg1}}"
|
|
||||||
else
|
|
||||||
echo "::set-output name=path::${{ github.workspace }}${{steps.command.outputs.arg2}}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Init branch
|
|
||||||
uses: xt0rted/pull-request-comment-branch@v1
|
|
||||||
id: comment-branch
|
|
||||||
|
|
||||||
process:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: init
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout ${{ needs.init.outputs.head_ref }}
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
|
||||||
fetch-depth: 0
|
|
||||||
ref: ${{ needs.init.outputs.head_ref }}
|
|
||||||
|
|
||||||
- name: Setup git
|
|
||||||
run: |
|
|
||||||
git config --local user.email "nextcloud-command@users.noreply.github.com"
|
|
||||||
git config --local user.name "nextcloud-command"
|
|
||||||
|
|
||||||
- name: Read package.json node and npm engines version
|
|
||||||
uses: skjnldsv/read-package-engines-version-actions@v1
|
|
||||||
id: package-engines-versions
|
|
||||||
with:
|
|
||||||
fallbackNode: '^12'
|
|
||||||
fallbackNpm: '^6'
|
|
||||||
|
|
||||||
- name: Set up node ${{ steps.package-engines-versions.outputs.nodeVersion }}
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: ${{ steps.package-engines-versions.outputs.nodeVersion }}
|
|
||||||
cache: npm
|
|
||||||
|
|
||||||
- name: Set up npm ${{ steps.package-engines-versions.outputs.npmVersion }}
|
|
||||||
run: npm i -g npm@"${{ steps.package-engines-versions.outputs.npmVersion }}"
|
|
||||||
|
|
||||||
- name: Install dependencies & build
|
|
||||||
run: |
|
|
||||||
npm ci
|
|
||||||
npm run build --if-present
|
|
||||||
|
|
||||||
- name: Commit and push default
|
|
||||||
if: ${{ needs.init.outputs.arg1 != 'fixup' && needs.init.outputs.arg1 != 'amend' }}
|
|
||||||
run: |
|
|
||||||
git add ${{ needs.init.outputs.git_path }}
|
|
||||||
git commit --signoff -m 'Compile assets'
|
|
||||||
git push origin ${{ needs.init.outputs.head_ref }}
|
|
||||||
|
|
||||||
- name: Commit and push fixup
|
|
||||||
if: ${{ needs.init.outputs.arg1 == 'fixup' }}
|
|
||||||
run: |
|
|
||||||
git add ${{ needs.init.outputs.git_path }}
|
|
||||||
git commit --fixup=HEAD --signoff
|
|
||||||
git push origin ${{ needs.init.outputs.head_ref }}
|
|
||||||
|
|
||||||
- name: Commit and push amend
|
|
||||||
if: ${{ needs.init.outputs.arg1 == 'amend' }}
|
|
||||||
run: |
|
|
||||||
git add ${{ needs.init.outputs.git_path }}
|
|
||||||
git commit --amend --no-edit --signoff
|
|
||||||
git push --force origin ${{ needs.init.outputs.head_ref }}
|
|
||||||
|
|
||||||
- name: Add reaction on failure
|
|
||||||
uses: peter-evans/create-or-update-comment@v1
|
|
||||||
if: failure()
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
|
||||||
repository: ${{ github.event.repository.full_name }}
|
|
||||||
comment-id: ${{ github.event.comment.id }}
|
|
||||||
reaction-type: "-1"
|
|
46
.github/workflows/command-rebase.yml
vendored
46
.github/workflows/command-rebase.yml
vendored
|
@ -1,46 +0,0 @@
|
||||||
# This workflow is provided via the organization template repository
|
|
||||||
#
|
|
||||||
# https://github.com/nextcloud/.github
|
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
|
||||||
|
|
||||||
name: Rebase command
|
|
||||||
|
|
||||||
on:
|
|
||||||
issue_comment:
|
|
||||||
types: created
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
rebase:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
# On pull requests and if the comment starts with `/rebase`
|
|
||||||
if: github.event.issue.pull_request != '' && startsWith(github.event.comment.body, '/rebase')
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Add reaction on start
|
|
||||||
uses: peter-evans/create-or-update-comment@v1
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
|
||||||
repository: ${{ github.event.repository.full_name }}
|
|
||||||
comment-id: ${{ github.event.comment.id }}
|
|
||||||
reaction-type: "+1"
|
|
||||||
|
|
||||||
- name: Checkout the latest code
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
|
||||||
|
|
||||||
- name: Automatic Rebase
|
|
||||||
uses: cirrus-actions/rebase@1.5
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.COMMAND_BOT_PAT }}
|
|
||||||
|
|
||||||
- name: Add reaction on failure
|
|
||||||
uses: peter-evans/create-or-update-comment@v1
|
|
||||||
if: failure()
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
|
||||||
repository: ${{ github.event.repository.full_name }}
|
|
||||||
comment-id: ${{ github.event.comment.id }}
|
|
||||||
reaction-type: "-1"
|
|
29
.github/workflows/dependabot-approve-merge.yml
vendored
29
.github/workflows/dependabot-approve-merge.yml
vendored
|
@ -1,29 +0,0 @@
|
||||||
# This workflow is provided via the organization template repository
|
|
||||||
#
|
|
||||||
# https://github.com/nextcloud/.github
|
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
|
||||||
|
|
||||||
name: Dependabot
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request_target:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- stable*
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
auto-merge:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
# Default github action approve
|
|
||||||
- uses: hmarr/auto-approve-action@v2
|
|
||||||
if: github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]'
|
|
||||||
with:
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
# Nextcloud bot approve and merge request
|
|
||||||
- uses: ahmadnassri/action-dependabot-auto-merge@v2
|
|
||||||
if: github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]'
|
|
||||||
with:
|
|
||||||
target: minor
|
|
||||||
github-token: ${{ secrets.DEPENDABOT_AUTOMERGE_TOKEN }}
|
|
12
.github/workflows/fixup.yml
vendored
12
.github/workflows/fixup.yml
vendored
|
@ -1,12 +0,0 @@
|
||||||
name: Pull request checks
|
|
||||||
on: pull_request
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
commit-message-check:
|
|
||||||
name: Block fixup and squash commits
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Run check
|
|
||||||
uses: xt0rted/block-autosquash-commits-action@main
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
111
.github/workflows/lint.yml
vendored
111
.github/workflows/lint.yml
vendored
|
@ -1,111 +0,0 @@
|
||||||
name: Lint
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- stable*
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
php:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
php-versions: ["7.3", "7.4", "8.0"]
|
|
||||||
|
|
||||||
name: php${{ matrix.php-versions }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Set up php ${{ matrix.php-versions }}
|
|
||||||
uses: shivammathur/setup-php@v2
|
|
||||||
with:
|
|
||||||
php-version: ${{ matrix.php-versions }}
|
|
||||||
coverage: none
|
|
||||||
|
|
||||||
- name: Lint
|
|
||||||
run: composer run lint
|
|
||||||
|
|
||||||
php-cs-fixer:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
php-versions: ["7.4"]
|
|
||||||
|
|
||||||
name: cs php${{ matrix.php-versions }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Set up php
|
|
||||||
uses: shivammathur/setup-php@v2
|
|
||||||
with:
|
|
||||||
php-version: ${{ matrix.php-versions }}
|
|
||||||
coverage: none
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: composer i
|
|
||||||
|
|
||||||
- name: Run coding standards check
|
|
||||||
run: composer run cs:check || ( echo 'Please run `composer run cs:fix` to format your code' && exit 1 )
|
|
||||||
|
|
||||||
node:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
name: eslint node
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Set up node
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: 14
|
|
||||||
|
|
||||||
- name: Set up npm7
|
|
||||||
run: npm i -g npm@7
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: npm ci
|
|
||||||
|
|
||||||
- name: Lint
|
|
||||||
run: npm run lint
|
|
||||||
|
|
||||||
stylelint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
name: stylelint node
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Set up node
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: 14
|
|
||||||
|
|
||||||
- name: Set up npm7
|
|
||||||
run: npm i -g npm@7
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: npm ci
|
|
||||||
|
|
||||||
- name: Lint
|
|
||||||
run: npm run stylelint
|
|
||||||
|
|
||||||
xml-linters:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@master
|
|
||||||
- name: Download schema
|
|
||||||
run: wget https://apps.nextcloud.com/schema/apps/info.xsd
|
|
||||||
- name: Lint info.xml
|
|
||||||
uses: ChristophWurst/xmllint-action@v1
|
|
||||||
with:
|
|
||||||
xml-file: ./appinfo/info.xml
|
|
||||||
xml-schema-file: ./info.xsd
|
|
52
.github/workflows/node.yml
vendored
52
.github/workflows/node.yml
vendored
|
@ -1,52 +0,0 @@
|
||||||
# This workflow is provided via the organization template repository
|
|
||||||
#
|
|
||||||
# https://github.com/nextcloud/.github
|
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
|
||||||
|
|
||||||
name: Node
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- stable*
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
name: node
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Read package.json node and npm engines version
|
|
||||||
uses: skjnldsv/read-package-engines-version-actions@v1.1
|
|
||||||
id: versions
|
|
||||||
with:
|
|
||||||
fallbackNode: '^12'
|
|
||||||
fallbackNpm: '^6'
|
|
||||||
|
|
||||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
|
||||||
|
|
||||||
- name: Set up npm ${{ steps.versions.outputs.npmVersion }}
|
|
||||||
run: npm i -g npm@"${{ steps.versions.outputs.npmVersion }}"
|
|
||||||
|
|
||||||
- name: Install dependencies & build
|
|
||||||
run: |
|
|
||||||
npm ci
|
|
||||||
npm run build --if-present
|
|
||||||
|
|
||||||
- name: Check webpack build changes
|
|
||||||
run: |
|
|
||||||
bash -c "[[ ! \"`git status --porcelain `\" ]] || exit 1"
|
|
||||||
|
|
||||||
- name: Show changes on failure
|
|
||||||
if: failure()
|
|
||||||
run: |
|
|
||||||
git status
|
|
||||||
git --no-pager diff
|
|
215
.github/workflows/phpunit.yml
vendored
215
.github/workflows/phpunit.yml
vendored
|
@ -1,215 +0,0 @@
|
||||||
name: PHPUnit
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- stable*
|
|
||||||
|
|
||||||
env:
|
|
||||||
APP_NAME: upschooling
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
php:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
# do not stop on another job's failure
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
php-versions: ['7.4']
|
|
||||||
databases: ['sqlite']
|
|
||||||
server-versions: ['master']
|
|
||||||
|
|
||||||
name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout server
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
repository: nextcloud/server
|
|
||||||
ref: ${{ matrix.server-versions }}
|
|
||||||
|
|
||||||
- name: Checkout submodules
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
|
|
||||||
git submodule sync --recursive
|
|
||||||
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
|
||||||
|
|
||||||
- name: Checkout app
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
path: apps/${{ env.APP_NAME }}
|
|
||||||
|
|
||||||
- name: Set up php ${{ matrix.php-versions }}
|
|
||||||
uses: shivammathur/setup-php@v2
|
|
||||||
with:
|
|
||||||
php-version: ${{ matrix.php-versions }}
|
|
||||||
tools: phpunit
|
|
||||||
extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite
|
|
||||||
coverage: none
|
|
||||||
|
|
||||||
- name: Set up PHPUnit
|
|
||||||
working-directory: apps/${{ env.APP_NAME }}
|
|
||||||
run: composer i
|
|
||||||
|
|
||||||
- name: Set up Nextcloud
|
|
||||||
env:
|
|
||||||
DB_PORT: 4444
|
|
||||||
run: |
|
|
||||||
mkdir data
|
|
||||||
./occ maintenance:install --verbose --database=${{ matrix.databases }} --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass password
|
|
||||||
./occ app:enable --force ${{ env.APP_NAME }}
|
|
||||||
php -S localhost:8080 &
|
|
||||||
|
|
||||||
- name: PHPUnit
|
|
||||||
working-directory: apps/${{ env.APP_NAME }}
|
|
||||||
run: ./vendor/phpunit/phpunit/phpunit -c phpunit.xml
|
|
||||||
|
|
||||||
- name: PHPUnit integration
|
|
||||||
working-directory: apps/${{ env.APP_NAME }}
|
|
||||||
run: ./vendor/phpunit/phpunit/phpunit -c phpunit.integration.xml
|
|
||||||
|
|
||||||
mysql:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
# do not stop on another job's failure
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
php-versions: ['7.3', '7.4']
|
|
||||||
databases: ['mysql']
|
|
||||||
server-versions: ['master']
|
|
||||||
|
|
||||||
name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}
|
|
||||||
|
|
||||||
services:
|
|
||||||
mysql:
|
|
||||||
image: mariadb:10.5
|
|
||||||
ports:
|
|
||||||
- 4444:3306/tcp
|
|
||||||
env:
|
|
||||||
MYSQL_ROOT_PASSWORD: rootpassword
|
|
||||||
options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 5
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout server
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
repository: nextcloud/server
|
|
||||||
ref: ${{ matrix.server-versions }}
|
|
||||||
|
|
||||||
- name: Checkout submodules
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
|
|
||||||
git submodule sync --recursive
|
|
||||||
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
|
||||||
|
|
||||||
- name: Checkout app
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
path: apps/${{ env.APP_NAME }}
|
|
||||||
|
|
||||||
- name: Set up php ${{ matrix.php-versions }}
|
|
||||||
uses: shivammathur/setup-php@v2
|
|
||||||
with:
|
|
||||||
php-version: ${{ matrix.php-versions }}
|
|
||||||
tools: phpunit
|
|
||||||
extensions: mbstring, iconv, fileinfo, intl, mysql, pdo_mysql
|
|
||||||
coverage: none
|
|
||||||
|
|
||||||
- name: Set up PHPUnit
|
|
||||||
working-directory: apps/${{ env.APP_NAME }}
|
|
||||||
run: composer i
|
|
||||||
|
|
||||||
- name: Set up Nextcloud
|
|
||||||
env:
|
|
||||||
DB_PORT: 4444
|
|
||||||
run: |
|
|
||||||
mkdir data
|
|
||||||
./occ maintenance:install --verbose --database=${{ matrix.databases }} --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass password
|
|
||||||
./occ app:enable --force ${{ env.APP_NAME }}
|
|
||||||
php -S localhost:8080 &
|
|
||||||
|
|
||||||
- name: PHPUnit
|
|
||||||
working-directory: apps/${{ env.APP_NAME }}
|
|
||||||
run: ./vendor/phpunit/phpunit/phpunit -c phpunit.xml
|
|
||||||
|
|
||||||
- name: PHPUnit integration
|
|
||||||
working-directory: apps/${{ env.APP_NAME }}
|
|
||||||
run: ./vendor/phpunit/phpunit/phpunit -c phpunit.integration.xml
|
|
||||||
|
|
||||||
pgsql:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
# do not stop on another job's failure
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
php-versions: ['7.4']
|
|
||||||
databases: ['pgsql']
|
|
||||||
server-versions: ['master']
|
|
||||||
|
|
||||||
name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}
|
|
||||||
|
|
||||||
services:
|
|
||||||
postgres:
|
|
||||||
image: postgres
|
|
||||||
ports:
|
|
||||||
- 4444:5432/tcp
|
|
||||||
env:
|
|
||||||
POSTGRES_USER: root
|
|
||||||
POSTGRES_PASSWORD: rootpassword
|
|
||||||
POSTGRES_DB: nextcloud
|
|
||||||
options: --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout server
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
repository: nextcloud/server
|
|
||||||
ref: ${{ matrix.server-versions }}
|
|
||||||
|
|
||||||
- name: Checkout submodules
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
|
|
||||||
git submodule sync --recursive
|
|
||||||
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
|
||||||
|
|
||||||
- name: Checkout app
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
path: apps/${{ env.APP_NAME }}
|
|
||||||
|
|
||||||
- name: Set up php ${{ matrix.php-versions }}
|
|
||||||
uses: shivammathur/setup-php@v2
|
|
||||||
with:
|
|
||||||
php-version: ${{ matrix.php-versions }}
|
|
||||||
tools: phpunit
|
|
||||||
extensions: mbstring, iconv, fileinfo, intl, pgsql, pdo_pgsql
|
|
||||||
coverage: none
|
|
||||||
|
|
||||||
- name: Set up PHPUnit
|
|
||||||
working-directory: apps/${{ env.APP_NAME }}
|
|
||||||
run: composer i
|
|
||||||
|
|
||||||
- name: Set up Nextcloud
|
|
||||||
env:
|
|
||||||
DB_PORT: 4444
|
|
||||||
run: |
|
|
||||||
mkdir data
|
|
||||||
./occ maintenance:install --verbose --database=${{ matrix.databases }} --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass password
|
|
||||||
./occ app:enable --force ${{ env.APP_NAME }}
|
|
||||||
php -S localhost:8080 &
|
|
||||||
|
|
||||||
- name: PHPUnit
|
|
||||||
working-directory: apps/${{ env.APP_NAME }}
|
|
||||||
run: ./vendor/phpunit/phpunit/phpunit -c phpunit.xml
|
|
||||||
|
|
||||||
- name: PHPUnit integration
|
|
||||||
working-directory: apps/${{ env.APP_NAME }}
|
|
||||||
run: ./vendor/phpunit/phpunit/phpunit -c phpunit.integration.xml
|
|
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -1,10 +1,6 @@
|
||||||
/.idea/
|
/.idea
|
||||||
*.iml
|
/build
|
||||||
/build/
|
|
||||||
node_modules/
|
|
||||||
/.php_cs.cache
|
|
||||||
/js/
|
|
||||||
|
|
||||||
### Composer ###
|
### Composer ###
|
||||||
composer.phar
|
composer.phar
|
||||||
/vendor/
|
/vendor
|
||||||
|
|
17
.php_cs.dist
17
.php_cs.dist
|
@ -1,17 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
require_once './vendor/autoload.php';
|
|
||||||
|
|
||||||
use Nextcloud\CodingStandard\Config;
|
|
||||||
|
|
||||||
$config = new Config();
|
|
||||||
$config
|
|
||||||
->getFinder()
|
|
||||||
->notPath('build')
|
|
||||||
->notPath('l10n')
|
|
||||||
->notPath('src')
|
|
||||||
->notPath('vendor')
|
|
||||||
->in(__DIR__);
|
|
||||||
return $config;
|
|
64
.travis.yml
Normal file
64
.travis.yml
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
sudo: false
|
||||||
|
dist: trusty
|
||||||
|
language: php
|
||||||
|
php:
|
||||||
|
- 5.6
|
||||||
|
- 7
|
||||||
|
- 7.1
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- CORE_BRANCH=stable15
|
||||||
|
matrix:
|
||||||
|
- DB=pgsql
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
allow_failures:
|
||||||
|
- env: DB=pgsql CORE_BRANCH=master
|
||||||
|
include:
|
||||||
|
- php: 5.6
|
||||||
|
env: DB=sqlite
|
||||||
|
- php: 5.6
|
||||||
|
env: DB=mysql
|
||||||
|
- php: 5.6
|
||||||
|
env: DB=pgsql CORE_BRANCH=master
|
||||||
|
fast_finish: true
|
||||||
|
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
# enable a display for running JavaScript tests
|
||||||
|
- export DISPLAY=:99.0
|
||||||
|
- sh -e /etc/init.d/xvfb start
|
||||||
|
- nvm install 8
|
||||||
|
- npm install -g npm@latest
|
||||||
|
- make
|
||||||
|
- make appstore
|
||||||
|
# install core
|
||||||
|
- cd ../
|
||||||
|
- git clone https://github.com/nextcloud/server.git --recursive --depth 1 -b $CORE_BRANCH nextcloud
|
||||||
|
- mv "$TRAVIS_BUILD_DIR" nextcloud/apps/upschooling
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- if [[ "$DB" == 'pgsql' ]]; then createuser -U travis -s oc_autotest; fi
|
||||||
|
- if [[ "$DB" == 'mysql' ]]; then mysql -u root -e 'create database oc_autotest;'; fi
|
||||||
|
- if [[ "$DB" == 'mysql' ]]; then mysql -u root -e "CREATE USER 'oc_autotest'@'localhost' IDENTIFIED BY '';"; fi
|
||||||
|
- if [[ "$DB" == 'mysql' ]]; then mysql -u root -e "grant all on oc_autotest.* to 'oc_autotest'@'localhost';"; fi
|
||||||
|
- cd nextcloud
|
||||||
|
- mkdir data
|
||||||
|
- ./occ maintenance:install --database-name oc_autotest --database-user oc_autotest --admin-user admin --admin-pass admin --database $DB --database-pass=''
|
||||||
|
- ./occ app:enable upschooling
|
||||||
|
- php -S localhost:8080 &
|
||||||
|
- cd apps/upschooling
|
||||||
|
|
||||||
|
script:
|
||||||
|
- make test
|
||||||
|
|
||||||
|
after_failure:
|
||||||
|
- cat ../../data/nextcloud.log
|
||||||
|
|
||||||
|
addons:
|
||||||
|
firefox: 'latest'
|
||||||
|
mariadb: '10.1'
|
||||||
|
|
||||||
|
services:
|
||||||
|
- postgresql
|
||||||
|
- mariadb
|
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,12 +0,0 @@
|
||||||
# Changelog
|
|
||||||
All notable changes to this project will be documented in this file.
|
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
||||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
||||||
|
|
||||||
|
|
||||||
## [0.0.2] - 2017-07-31
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- First release
|
|
172
Makefile
172
Makefile
|
@ -1,17 +1,73 @@
|
||||||
# This file is licensed under the Affero General Public License version 3 or
|
# This file is licensed under the Affero General Public License version 3 or
|
||||||
# later. See the COPYING file.
|
# later. See the COPYING file.
|
||||||
|
# @author Bernhard Posselt <dev@bernhard-posselt.com>
|
||||||
|
# @copyright Bernhard Posselt 2016
|
||||||
|
|
||||||
|
# Generic Makefile for building and packaging a Nextcloud app which uses npm and
|
||||||
|
# Composer.
|
||||||
|
#
|
||||||
|
# Dependencies:
|
||||||
|
# * make
|
||||||
|
# * which
|
||||||
|
# * curl: used if phpunit and composer are not installed to fetch them from the web
|
||||||
|
# * tar: for building the archive
|
||||||
|
# * npm: for building and testing everything JS
|
||||||
|
#
|
||||||
|
# If no composer.json is in the app root directory, the Composer step
|
||||||
|
# will be skipped. The same goes for the package.json which can be located in
|
||||||
|
# the app root or the js/ directory.
|
||||||
|
#
|
||||||
|
# The npm command by launches the npm build script:
|
||||||
|
#
|
||||||
|
# npm run build
|
||||||
|
#
|
||||||
|
# The npm test command launches the npm test script:
|
||||||
|
#
|
||||||
|
# npm run test
|
||||||
|
#
|
||||||
|
# The idea behind this is to be completely testing and build tool agnostic. All
|
||||||
|
# build tools and additional package managers should be installed locally in
|
||||||
|
# your project, since this won't pollute people's global namespace.
|
||||||
|
#
|
||||||
|
# The following npm scripts in your package.json install and update the bower
|
||||||
|
# and npm dependencies and use gulp as build system (notice how everything is
|
||||||
|
# run from the node_modules folder):
|
||||||
|
#
|
||||||
|
# "scripts": {
|
||||||
|
# "test": "node node_modules/gulp-cli/bin/gulp.js karma",
|
||||||
|
# "prebuild": "npm install && node_modules/bower/bin/bower install && node_modules/bower/bin/bower update",
|
||||||
|
# "build": "node node_modules/gulp-cli/bin/gulp.js"
|
||||||
|
# },
|
||||||
|
|
||||||
app_name=$(notdir $(CURDIR))
|
app_name=$(notdir $(CURDIR))
|
||||||
build_tools_directory=$(CURDIR)/build/tools
|
build_tools_directory=$(CURDIR)/build/tools
|
||||||
|
source_build_directory=$(CURDIR)/build/artifacts/source
|
||||||
|
source_package_name=$(source_build_directory)/$(app_name)
|
||||||
|
appstore_build_directory=$(CURDIR)/build/artifacts/appstore
|
||||||
|
appstore_package_name=$(appstore_build_directory)/$(app_name)
|
||||||
|
npm=$(shell which npm 2> /dev/null)
|
||||||
composer=$(shell which composer 2> /dev/null)
|
composer=$(shell which composer 2> /dev/null)
|
||||||
|
|
||||||
all: dev-setup lint build-js-production test
|
all: build
|
||||||
|
|
||||||
# Dev env management
|
|
||||||
dev-setup: clean clean-dev composer npm-init
|
|
||||||
|
|
||||||
|
# Fetches the PHP and JS dependencies and compiles the JS. If no composer.json
|
||||||
|
# is present, the composer step is skipped, if no package.json or js/package.json
|
||||||
|
# is present, the npm step is skipped
|
||||||
|
.PHONY: build
|
||||||
|
build:
|
||||||
|
ifneq (,$(wildcard $(CURDIR)/composer.json))
|
||||||
|
make composer
|
||||||
|
endif
|
||||||
|
ifneq (,$(wildcard $(CURDIR)/package.json))
|
||||||
|
make npm
|
||||||
|
endif
|
||||||
|
ifneq (,$(wildcard $(CURDIR)/js/package.json))
|
||||||
|
make npm
|
||||||
|
endif
|
||||||
|
|
||||||
# Installs and updates the composer dependencies. If composer is not installed
|
# Installs and updates the composer dependencies. If composer is not installed
|
||||||
# a copy is fetched from the web
|
# a copy is fetched from the web
|
||||||
|
.PHONY: composer
|
||||||
composer:
|
composer:
|
||||||
ifeq (, $(composer))
|
ifeq (, $(composer))
|
||||||
@echo "No composer command available, downloading a copy from the web"
|
@echo "No composer command available, downloading a copy from the web"
|
||||||
|
@ -19,53 +75,81 @@ ifeq (, $(composer))
|
||||||
curl -sS https://getcomposer.org/installer | php
|
curl -sS https://getcomposer.org/installer | php
|
||||||
mv composer.phar $(build_tools_directory)
|
mv composer.phar $(build_tools_directory)
|
||||||
php $(build_tools_directory)/composer.phar install --prefer-dist
|
php $(build_tools_directory)/composer.phar install --prefer-dist
|
||||||
php $(build_tools_directory)/composer.phar update --prefer-dist
|
|
||||||
else
|
else
|
||||||
composer install --prefer-dist
|
composer install --prefer-dist
|
||||||
composer update --prefer-dist
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
npm-init:
|
# Installs npm dependencies
|
||||||
npm ci
|
.PHONY: npm
|
||||||
|
npm:
|
||||||
npm-update:
|
ifeq (,$(wildcard $(CURDIR)/package.json))
|
||||||
npm update
|
cd js && $(npm) run build
|
||||||
|
else
|
||||||
# Building
|
|
||||||
build-js:
|
|
||||||
npm run dev
|
|
||||||
|
|
||||||
build-js-production:
|
|
||||||
npm run build
|
npm run build
|
||||||
|
endif
|
||||||
|
|
||||||
watch-js:
|
# Removes the appstore build
|
||||||
npm run watch
|
.PHONY: clean
|
||||||
|
|
||||||
serve-js:
|
|
||||||
npm run serve
|
|
||||||
|
|
||||||
# Linting
|
|
||||||
lint:
|
|
||||||
npm run lint
|
|
||||||
|
|
||||||
lint-fix:
|
|
||||||
npm run lint:fix
|
|
||||||
|
|
||||||
# Style linting
|
|
||||||
stylelint:
|
|
||||||
npm run stylelint
|
|
||||||
|
|
||||||
stylelint-fix:
|
|
||||||
npm run stylelint:fix
|
|
||||||
|
|
||||||
# Cleaning
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf js/*
|
rm -rf ./build
|
||||||
|
|
||||||
clean-dev:
|
# Same as clean but also removes dependencies installed by composer, bower and
|
||||||
|
# npm
|
||||||
|
.PHONY: distclean
|
||||||
|
distclean: clean
|
||||||
|
rm -rf vendor
|
||||||
rm -rf node_modules
|
rm -rf node_modules
|
||||||
|
rm -rf js/vendor
|
||||||
|
rm -rf js/node_modules
|
||||||
|
|
||||||
# Tests
|
# Builds the source and appstore package
|
||||||
test:
|
.PHONY: dist
|
||||||
./vendor/phpunit/phpunit/phpunit -c phpunit.xml
|
dist:
|
||||||
./vendor/phpunit/phpunit/phpunit -c phpunit.integration.xml
|
make source
|
||||||
|
make appstore
|
||||||
|
|
||||||
|
# Builds the source package
|
||||||
|
.PHONY: source
|
||||||
|
source:
|
||||||
|
rm -rf $(source_build_directory)
|
||||||
|
mkdir -p $(source_build_directory)
|
||||||
|
tar cvzf $(source_package_name).tar.gz ../$(app_name) \
|
||||||
|
--exclude-vcs \
|
||||||
|
--exclude="../$(app_name)/build" \
|
||||||
|
--exclude="../$(app_name)/js/node_modules" \
|
||||||
|
--exclude="../$(app_name)/node_modules" \
|
||||||
|
--exclude="../$(app_name)/*.log" \
|
||||||
|
--exclude="../$(app_name)/js/*.log" \
|
||||||
|
|
||||||
|
# Builds the source package for the app store, ignores php and js tests
|
||||||
|
.PHONY: appstore
|
||||||
|
appstore:
|
||||||
|
rm -rf $(appstore_build_directory)
|
||||||
|
mkdir -p $(appstore_build_directory)
|
||||||
|
tar cvzf $(appstore_package_name).tar.gz ../$(app_name) \
|
||||||
|
--exclude-vcs \
|
||||||
|
--exclude="../$(app_name)/build" \
|
||||||
|
--exclude="../$(app_name)/tests" \
|
||||||
|
--exclude="../$(app_name)/Makefile" \
|
||||||
|
--exclude="../$(app_name)/*.log" \
|
||||||
|
--exclude="../$(app_name)/phpunit*xml" \
|
||||||
|
--exclude="../$(app_name)/composer.*" \
|
||||||
|
--exclude="../$(app_name)/js/node_modules" \
|
||||||
|
--exclude="../$(app_name)/js/tests" \
|
||||||
|
--exclude="../$(app_name)/js/test" \
|
||||||
|
--exclude="../$(app_name)/js/*.log" \
|
||||||
|
--exclude="../$(app_name)/js/package.json" \
|
||||||
|
--exclude="../$(app_name)/js/bower.json" \
|
||||||
|
--exclude="../$(app_name)/js/karma.*" \
|
||||||
|
--exclude="../$(app_name)/js/protractor.*" \
|
||||||
|
--exclude="../$(app_name)/package.json" \
|
||||||
|
--exclude="../$(app_name)/bower.json" \
|
||||||
|
--exclude="../$(app_name)/karma.*" \
|
||||||
|
--exclude="../$(app_name)/protractor\.*" \
|
||||||
|
--exclude="../$(app_name)/.*" \
|
||||||
|
--exclude="../$(app_name)/js/.*" \
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test: composer
|
||||||
|
$(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.xml
|
||||||
|
$(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.integration.xml
|
||||||
|
|
49
README.md
49
README.md
|
@ -1,31 +1,52 @@
|
||||||
# UPschooling
|
# U Pschooling
|
||||||
|
|
||||||
Place this app in **nextcloud/apps/**
|
Place this app in **nextcloud/apps/**
|
||||||
|
|
||||||
[![PHPUnit GitHub Action](https://github.com/nextcloud/app-tutorial/workflows/PHPUnit/badge.svg)](https://github.com/nextcloud/app-tutorial/actions?query=workflow%3APHPUnit)
|
## Building the app
|
||||||
[![Node GitHub Action](https://github.com/nextcloud/app-tutorial/workflows/Node/badge.svg)](https://github.com/nextcloud/app-tutorial/actions?query=workflow%3ANode)
|
|
||||||
[![Lint GitHub Action](https://github.com/nextcloud/app-tutorial/workflows/Lint/badge.svg)](https://github.com/nextcloud/app-tutorial/actions?query=workflow%3ALint)
|
|
||||||
|
|
||||||
This is the [tutorial app](https://docs.nextcloud.com/server/latest/developer_manual/app_development/tutorial.html) which shows how to develop a very simple notes app.
|
The app can be built by using the provided Makefile by running:
|
||||||
|
|
||||||
## Installing dependencies
|
make
|
||||||
|
|
||||||
|
This requires the following things to be present:
|
||||||
|
* make
|
||||||
|
* which
|
||||||
|
* tar: for building the archive
|
||||||
|
* curl: used if phpunit and composer are not installed to fetch them from the web
|
||||||
|
* npm: for building and testing everything JS, only required if a package.json is placed inside the **js/** folder
|
||||||
|
|
||||||
|
The make command will install or update Composer dependencies if a composer.json is present and also **npm run build** if a package.json is present in the **js/** folder. The npm **build** script should use local paths for build systems and package managers, so people that simply want to build the app won't need to install npm libraries globally, e.g.:
|
||||||
|
|
||||||
|
**package.json**:
|
||||||
|
```json
|
||||||
|
"scripts": {
|
||||||
|
"test": "node node_modules/gulp-cli/bin/gulp.js karma",
|
||||||
|
"prebuild": "npm install && node_modules/bower/bin/bower install && node_modules/bower/bin/bower update",
|
||||||
|
"build": "node node_modules/gulp-cli/bin/gulp.js"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Publish to App Store
|
||||||
|
|
||||||
|
First get an account for the [App Store](http://apps.nextcloud.com/) then run:
|
||||||
|
|
||||||
|
make && make appstore
|
||||||
|
|
||||||
|
The archive is located in build/artifacts/appstore and can then be uploaded to the App Store.
|
||||||
|
|
||||||
|
## Running tests
|
||||||
|
You can use the provided Makefile to run all tests by using:
|
||||||
|
|
||||||
|
make test
|
||||||
|
|
||||||
|
This will run the PHP unit and integration tests and if a package.json is present in the **js/** folder will execute **npm run test**
|
||||||
|
|
||||||
|
Of course you can also install [PHPUnit](http://phpunit.de/getting-started.html) and use the configurations directly:
|
||||||
|
|
||||||
make composer
|
phpunit -c phpunit.xml
|
||||||
|
|
||||||
## Frontend development
|
or:
|
||||||
|
|
||||||
The app tutorial also shows the very basic implementation of an app frontend using [Vue.js](https://vuejs.org/). To build the frontend code after doing changes to its source in `src/` requires to have Node and npm installed.
|
phpunit -c phpunit.integration.xml
|
||||||
|
|
||||||
- 👩💻 Run `make dev-setup` to install the frontend dependencies
|
for integration tests
|
||||||
- 🏗 To build the Javascript whenever you make changes, run `make build-js`
|
|
||||||
|
|
||||||
To continuously run the build when editing source files you can make use of the `make watch-js` command.
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
|
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
|
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
|
||||||
<id>upschooling</id>
|
<id>upschooling</id>
|
||||||
<name>UPschooling</name>
|
<name>U Pschooling</name>
|
||||||
<summary>UPschooling Support Platform</summary>
|
<summary>UPschooling Support Platform</summary>
|
||||||
<description><![CDATA[Ticketsystem für UPschooling]]></description>
|
<description><![CDATA[Ticketsystem für UPschooling]]></description>
|
||||||
<version>0.0.1</version>
|
<version>0.0.1</version>
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<navigations>
|
<navigations>
|
||||||
<navigation>
|
<navigation>
|
||||||
<name>Support</name>
|
<name>U Pschooling</name>
|
||||||
<route>upschooling.page.index</route>
|
<route>upschooling.page.index</route>
|
||||||
</navigation>
|
</navigation>
|
||||||
</navigations>
|
</navigations>
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Create your routes in here. The name is the lowercase name of the controller
|
||||||
|
* without the controller part, the stuff after the hash is the method.
|
||||||
|
* e.g. page#index -> OCA\UPschooling\Controller\PageController->index()
|
||||||
|
*
|
||||||
|
* The controller class has to be registered in the application.php file since
|
||||||
|
* it's instantiated in there
|
||||||
|
*/
|
||||||
return [
|
return [
|
||||||
'resources' => [
|
'routes' => [
|
||||||
'note' => ['url' => '/notes'],
|
['name' => 'page#index', 'url' => '/', 'verb' => 'GET'],
|
||||||
'note_api' => ['url' => '/api/0.1/notes']
|
['name' => 'page#do_echo', 'url' => '/echo', 'verb' => 'POST'],
|
||||||
],
|
]
|
||||||
'routes' => [
|
|
||||||
['name' => 'page#index', 'url' => '/', 'verb' => 'GET'],
|
|
||||||
['name' => 'note_api#preflighted_cors', 'url' => '/api/0.1/{path}',
|
|
||||||
'verb' => 'OPTIONS', 'requirements' => ['path' => '.+']]
|
|
||||||
]
|
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
const babelConfig = require('@nextcloud/babel-config')
|
|
||||||
|
|
||||||
module.exports = babelConfig
|
|
|
@ -10,19 +10,6 @@
|
||||||
],
|
],
|
||||||
"require": {},
|
"require": {},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^8.5",
|
"phpunit/phpunit": "^5.4"
|
||||||
"nextcloud/coding-standard": "^0.5.0"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"optimize-autoloader": true,
|
|
||||||
"classmap-authoritative": true,
|
|
||||||
"platform": {
|
|
||||||
"php": "7.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"lint": "find . -name \\*.php -not -path './vendor/*' -not -path './build/*' -print0 | xargs -0 -n1 php -l",
|
|
||||||
"cs:check": "php-cs-fixer fix --dry-run --diff",
|
|
||||||
"cs:fix": "php-cs-fixer fix"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
2405
composer.lock
generated
2405
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -1,34 +1,3 @@
|
||||||
#app-content-wrapper {
|
#hello {
|
||||||
height: 100%;
|
color: red;
|
||||||
}
|
|
||||||
|
|
||||||
#editor {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#editor .input {
|
|
||||||
height: calc(100% - 51px);
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#editor .save {
|
|
||||||
height: 50px;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
border-top: 1px solid #ccc;
|
|
||||||
background-color: #fafafa;
|
|
||||||
}
|
|
||||||
|
|
||||||
#editor textarea {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
border: 0;
|
|
||||||
margin: 0;
|
|
||||||
border-radius: 0;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
#editor button {
|
|
||||||
height: 44px;
|
|
||||||
}
|
}
|
0
js/script.js
Normal file
0
js/script.js
Normal file
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OCA\UPschooling\AppInfo;
|
|
||||||
|
|
||||||
use OCP\AppFramework\App;
|
|
||||||
|
|
||||||
class Application extends App {
|
|
||||||
public const APP_ID = 'upschooling';
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
parent::__construct(self::APP_ID);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OCA\UPschooling\Controller;
|
|
||||||
|
|
||||||
use Closure;
|
|
||||||
|
|
||||||
use OCP\AppFramework\Http;
|
|
||||||
use OCP\AppFramework\Http\DataResponse;
|
|
||||||
|
|
||||||
use OCA\UPschooling\Service\NoteNotFound;
|
|
||||||
|
|
||||||
trait Errors {
|
|
||||||
protected function handleNotFound(Closure $callback): DataResponse {
|
|
||||||
try {
|
|
||||||
return new DataResponse($callback());
|
|
||||||
} catch (NoteNotFound $e) {
|
|
||||||
$message = ['message' => $e->getMessage()];
|
|
||||||
return new DataResponse($message, Http::STATUS_NOT_FOUND);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OCA\UPschooling\Controller;
|
|
||||||
|
|
||||||
use OCA\UPschooling\AppInfo\Application;
|
|
||||||
use OCA\UPschooling\Service\NoteService;
|
|
||||||
use OCP\AppFramework\ApiController;
|
|
||||||
use OCP\AppFramework\Http\DataResponse;
|
|
||||||
use OCP\IRequest;
|
|
||||||
|
|
||||||
class NoteApiController extends ApiController {
|
|
||||||
/** @var NoteService */
|
|
||||||
private $service;
|
|
||||||
|
|
||||||
/** @var string */
|
|
||||||
private $userId;
|
|
||||||
|
|
||||||
use Errors;
|
|
||||||
|
|
||||||
public function __construct(IRequest $request,
|
|
||||||
NoteService $service,
|
|
||||||
$userId) {
|
|
||||||
parent::__construct(Application::APP_ID, $request);
|
|
||||||
$this->service = $service;
|
|
||||||
$this->userId = $userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @CORS
|
|
||||||
* @NoCSRFRequired
|
|
||||||
* @NoAdminRequired
|
|
||||||
*/
|
|
||||||
public function index(): DataResponse {
|
|
||||||
return new DataResponse($this->service->findAll($this->userId));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @CORS
|
|
||||||
* @NoCSRFRequired
|
|
||||||
* @NoAdminRequired
|
|
||||||
*/
|
|
||||||
public function show(int $id): DataResponse {
|
|
||||||
return $this->handleNotFound(function () use ($id) {
|
|
||||||
return $this->service->find($id, $this->userId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @CORS
|
|
||||||
* @NoCSRFRequired
|
|
||||||
* @NoAdminRequired
|
|
||||||
*/
|
|
||||||
public function create(string $title, string $content): DataResponse {
|
|
||||||
return new DataResponse($this->service->create($title, $content,
|
|
||||||
$this->userId));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @CORS
|
|
||||||
* @NoCSRFRequired
|
|
||||||
* @NoAdminRequired
|
|
||||||
*/
|
|
||||||
public function update(int $id, string $title,
|
|
||||||
string $content): DataResponse {
|
|
||||||
return $this->handleNotFound(function () use ($id, $title, $content) {
|
|
||||||
return $this->service->update($id, $title, $content, $this->userId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @CORS
|
|
||||||
* @NoCSRFRequired
|
|
||||||
* @NoAdminRequired
|
|
||||||
*/
|
|
||||||
public function destroy(int $id): DataResponse {
|
|
||||||
return $this->handleNotFound(function () use ($id) {
|
|
||||||
return $this->service->delete($id, $this->userId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OCA\UPschooling\Controller;
|
|
||||||
|
|
||||||
use OCA\UPschooling\AppInfo\Application;
|
|
||||||
use OCA\UPschooling\Service\NoteService;
|
|
||||||
use OCP\AppFramework\Controller;
|
|
||||||
use OCP\AppFramework\Http\DataResponse;
|
|
||||||
use OCP\IRequest;
|
|
||||||
|
|
||||||
class NoteController extends Controller {
|
|
||||||
/** @var NoteService */
|
|
||||||
private $service;
|
|
||||||
|
|
||||||
/** @var string */
|
|
||||||
private $userId;
|
|
||||||
|
|
||||||
use Errors;
|
|
||||||
|
|
||||||
public function __construct(IRequest $request,
|
|
||||||
NoteService $service,
|
|
||||||
$userId) {
|
|
||||||
parent::__construct(Application::APP_ID, $request);
|
|
||||||
$this->service = $service;
|
|
||||||
$this->userId = $userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @NoAdminRequired
|
|
||||||
*/
|
|
||||||
public function index(): DataResponse {
|
|
||||||
return new DataResponse($this->service->findAll($this->userId));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @NoAdminRequired
|
|
||||||
*/
|
|
||||||
public function show(int $id): DataResponse {
|
|
||||||
return $this->handleNotFound(function () use ($id) {
|
|
||||||
return $this->service->find($id, $this->userId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @NoAdminRequired
|
|
||||||
*/
|
|
||||||
public function create(string $title, string $content): DataResponse {
|
|
||||||
return new DataResponse($this->service->create($title, $content,
|
|
||||||
$this->userId));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @NoAdminRequired
|
|
||||||
*/
|
|
||||||
public function update(int $id, string $title,
|
|
||||||
string $content): DataResponse {
|
|
||||||
return $this->handleNotFound(function () use ($id, $title, $content) {
|
|
||||||
return $this->service->update($id, $title, $content, $this->userId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @NoAdminRequired
|
|
||||||
*/
|
|
||||||
public function destroy(int $id): DataResponse {
|
|
||||||
return $this->handleNotFound(function () use ($id) {
|
|
||||||
return $this->service->delete($id, $this->userId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +1,31 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace OCA\UPschooling\Controller;
|
namespace OCA\UPschooling\Controller;
|
||||||
|
|
||||||
use OCA\UPschooling\AppInfo\Application;
|
|
||||||
use OCP\AppFramework\Controller;
|
|
||||||
use OCP\AppFramework\Http\TemplateResponse;
|
|
||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
use OCP\Util;
|
use OCP\AppFramework\Http\TemplateResponse;
|
||||||
|
use OCP\AppFramework\Http\DataResponse;
|
||||||
|
use OCP\AppFramework\Controller;
|
||||||
|
|
||||||
class PageController extends Controller {
|
class PageController extends Controller {
|
||||||
public function __construct(IRequest $request) {
|
private $userId;
|
||||||
parent::__construct(Application::APP_ID, $request);
|
|
||||||
|
public function __construct($AppName, IRequest $request, $UserId){
|
||||||
|
parent::__construct($AppName, $request);
|
||||||
|
$this->userId = $UserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* CAUTION: the @Stuff turns off security checks; for this page no admin is
|
||||||
|
* required and no CSRF check. If you don't know what CSRF is, read
|
||||||
|
* it up in the docs or you might create a security hole. This is
|
||||||
|
* basically the only required method to add this exemption, don't
|
||||||
|
* add it to any other method if you don't exactly know what it does
|
||||||
|
*
|
||||||
* @NoAdminRequired
|
* @NoAdminRequired
|
||||||
* @NoCSRFRequired
|
* @NoCSRFRequired
|
||||||
*
|
|
||||||
* Render default template
|
|
||||||
*/
|
*/
|
||||||
public function index() {
|
public function index() {
|
||||||
Util::addScript(Application::APP_ID, 'upschooling-main');
|
return new TemplateResponse('upschooling', 'index'); // templates/index.php
|
||||||
|
|
||||||
return new TemplateResponse(Application::APP_ID, 'main');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OCA\UPschooling\Db;
|
|
||||||
|
|
||||||
use JsonSerializable;
|
|
||||||
|
|
||||||
use OCP\AppFramework\Db\Entity;
|
|
||||||
|
|
||||||
class Note extends Entity implements JsonSerializable {
|
|
||||||
protected $title;
|
|
||||||
protected $content;
|
|
||||||
protected $userId;
|
|
||||||
|
|
||||||
public function jsonSerialize(): array {
|
|
||||||
return [
|
|
||||||
'id' => $this->id,
|
|
||||||
'title' => $this->title,
|
|
||||||
'content' => $this->content
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OCA\UPschooling\Db;
|
|
||||||
|
|
||||||
use OCP\AppFramework\Db\DoesNotExistException;
|
|
||||||
use OCP\AppFramework\Db\Entity;
|
|
||||||
use OCP\AppFramework\Db\QBMapper;
|
|
||||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
|
||||||
use OCP\IDBConnection;
|
|
||||||
|
|
||||||
class NoteMapper extends QBMapper {
|
|
||||||
public function __construct(IDBConnection $db) {
|
|
||||||
parent::__construct($db, 'upschooling', Note::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $id
|
|
||||||
* @param string $userId
|
|
||||||
* @return Entity|Note
|
|
||||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
|
||||||
* @throws DoesNotExistException
|
|
||||||
*/
|
|
||||||
public function find(int $id, string $userId): Note {
|
|
||||||
/* @var $qb IQueryBuilder */
|
|
||||||
$qb = $this->db->getQueryBuilder();
|
|
||||||
$qb->select('*')
|
|
||||||
->from('upschooling')
|
|
||||||
->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)))
|
|
||||||
->andWhere($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)));
|
|
||||||
return $this->findEntity($qb);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $userId
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function findAll(string $userId): array {
|
|
||||||
/* @var $qb IQueryBuilder */
|
|
||||||
$qb = $this->db->getQueryBuilder();
|
|
||||||
$qb->select('*')
|
|
||||||
->from('upschooling')
|
|
||||||
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)));
|
|
||||||
return $this->findEntities($qb);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace OCA\UPschooling\Migration;
|
|
||||||
|
|
||||||
use Closure;
|
|
||||||
use OCP\DB\ISchemaWrapper;
|
|
||||||
use OCP\Migration\SimpleMigrationStep;
|
|
||||||
use OCP\Migration\IOutput;
|
|
||||||
|
|
||||||
class Version000000Date20181013124731 extends SimpleMigrationStep {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param IOutput $output
|
|
||||||
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
|
|
||||||
* @param array $options
|
|
||||||
* @return null|ISchemaWrapper
|
|
||||||
*/
|
|
||||||
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
|
|
||||||
/** @var ISchemaWrapper $schema */
|
|
||||||
$schema = $schemaClosure();
|
|
||||||
|
|
||||||
if (!$schema->hasTable('upschooling')) {
|
|
||||||
$table = $schema->createTable('upschooling');
|
|
||||||
$table->addColumn('id', 'integer', [
|
|
||||||
'autoincrement' => true,
|
|
||||||
'notnull' => true,
|
|
||||||
]);
|
|
||||||
$table->addColumn('title', 'string', [
|
|
||||||
'notnull' => true,
|
|
||||||
'length' => 200
|
|
||||||
]);
|
|
||||||
$table->addColumn('user_id', 'string', [
|
|
||||||
'notnull' => true,
|
|
||||||
'length' => 200,
|
|
||||||
]);
|
|
||||||
$table->addColumn('content', 'text', [
|
|
||||||
'notnull' => true,
|
|
||||||
'default' => ''
|
|
||||||
]);
|
|
||||||
|
|
||||||
$table->setPrimaryKey(['id']);
|
|
||||||
$table->addIndex(['user_id'], 'upschooling_user_id_index');
|
|
||||||
}
|
|
||||||
return $schema;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OCA\UPschooling\Service;
|
|
||||||
|
|
||||||
class NoteNotFound extends \Exception {
|
|
||||||
}
|
|
|
@ -1,76 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OCA\UPschooling\Service;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
use OCP\AppFramework\Db\DoesNotExistException;
|
|
||||||
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
|
|
||||||
|
|
||||||
use OCA\UPschooling\Db\Note;
|
|
||||||
use OCA\UPschooling\Db\NoteMapper;
|
|
||||||
|
|
||||||
class NoteService {
|
|
||||||
|
|
||||||
/** @var NoteMapper */
|
|
||||||
private $mapper;
|
|
||||||
|
|
||||||
public function __construct(NoteMapper $mapper) {
|
|
||||||
$this->mapper = $mapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function findAll(string $userId): array {
|
|
||||||
return $this->mapper->findAll($userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function handleException(Exception $e): void {
|
|
||||||
if ($e instanceof DoesNotExistException ||
|
|
||||||
$e instanceof MultipleObjectsReturnedException) {
|
|
||||||
throw new NoteNotFound($e->getMessage());
|
|
||||||
} else {
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function find($id, $userId) {
|
|
||||||
try {
|
|
||||||
return $this->mapper->find($id, $userId);
|
|
||||||
|
|
||||||
// in order to be able to plug in different storage backends like files
|
|
||||||
// for instance it is a good idea to turn storage related exceptions
|
|
||||||
// into service related exceptions so controllers and service users
|
|
||||||
// have to deal with only one type of exception
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$this->handleException($e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create($title, $content, $userId) {
|
|
||||||
$note = new Note();
|
|
||||||
$note->setTitle($title);
|
|
||||||
$note->setContent($content);
|
|
||||||
$note->setUserId($userId);
|
|
||||||
return $this->mapper->insert($note);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update($id, $title, $content, $userId) {
|
|
||||||
try {
|
|
||||||
$note = $this->mapper->find($id, $userId);
|
|
||||||
$note->setTitle($title);
|
|
||||||
$note->setContent($content);
|
|
||||||
return $this->mapper->update($note);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$this->handleException($e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete($id, $userId) {
|
|
||||||
try {
|
|
||||||
$note = $this->mapper->find($id, $userId);
|
|
||||||
$this->mapper->delete($note);
|
|
||||||
return $note;
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$this->handleException($e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 208 KiB |
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 133 KiB |
25700
package-lock.json
generated
25700
package-lock.json
generated
File diff suppressed because it is too large
Load diff
50
package.json
50
package.json
|
@ -1,50 +0,0 @@
|
||||||
{
|
|
||||||
"name": "upschooling",
|
|
||||||
"description": "A simple Nextcloud app tutorial for building a notes app",
|
|
||||||
"version": "19.0.0",
|
|
||||||
"author": "Julius Härtl <jus@bitgrid.net",
|
|
||||||
"contributors": [
|
|
||||||
"John Molakvoæ <skjnldsv@protonmail.com>"
|
|
||||||
],
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/nextcloud/app-tutorial/issues"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"url": "https://github.com/nextcloud/app-tutorial",
|
|
||||||
"type": "git"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/nextcloud/app-tutorial",
|
|
||||||
"license": "agpl",
|
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"build": "NODE_ENV=production webpack --progress --config webpack.js",
|
|
||||||
"dev": "NODE_ENV=development webpack --progress --config webpack.js",
|
|
||||||
"watch": "NODE_ENV=development webpack --progress --watch --config webpack.js",
|
|
||||||
"serve": "NODE_ENV=development webpack serve --progress --config webpack.js",
|
|
||||||
"lint": "eslint --ext .js,.vue src",
|
|
||||||
"lint:fix": "eslint --ext .js,.vue src --fix",
|
|
||||||
"stylelint": "stylelint css/*.css css/*.scss src/**/*.scss src/**/*.vue",
|
|
||||||
"stylelint:fix": "stylelint css/*.css css/*.scss src/**/*.scss src/**/*.vue --fix"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@nextcloud/axios": "^1.6.0",
|
|
||||||
"@nextcloud/dialogs": "^3.1.2",
|
|
||||||
"@nextcloud/router": "^1.2.0",
|
|
||||||
"@nextcloud/vue": "^3.10.1",
|
|
||||||
"vue": "^2.6.14"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
"extends @nextcloud/browserslist-config"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.0.0",
|
|
||||||
"npm": ">=7.0.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@nextcloud/babel-config": "^1.0.0",
|
|
||||||
"@nextcloud/browserslist-config": "^2.1.0",
|
|
||||||
"@nextcloud/eslint-config": "^6.1.0",
|
|
||||||
"@nextcloud/stylelint-config": "^1.0.0-beta.0",
|
|
||||||
"@nextcloud/webpack-vue-config": "^4.1.0"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,3 +8,4 @@ DIR="${0%/*}"
|
||||||
podman unshare -- chown -R 33 "$DIR"
|
podman unshare -- chown -R 33 "$DIR"
|
||||||
podman unshare -- chgrp -R 0 "$DIR"
|
podman unshare -- chgrp -R 0 "$DIR"
|
||||||
podman unshare -- chmod -R ug+rw "$DIR"
|
podman unshare -- chmod -R ug+rw "$DIR"
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,5 @@ DIR="${0%/*}"
|
||||||
podman run -d --name=nextcloud --replace=true -p 8080:80 -v "$DIR:/var/www/html/custom_apps/upschooling" docker.io/nextcloud
|
podman run -d --name=nextcloud --replace=true -p 8080:80 -v "$DIR:/var/www/html/custom_apps/upschooling" docker.io/nextcloud
|
||||||
podman exec nextcloud chown -R 33 /var/www/html/custom_apps
|
podman exec nextcloud chown -R 33 /var/www/html/custom_apps
|
||||||
"$DIR/podman-reown.sh"
|
"$DIR/podman-reown.sh"
|
||||||
podman exec --user 33 nextcloud bash -c 'cd /var/www/html/custom_apps/upschooling && make composer'
|
podman exec --user 33 nextcloud bash -c 'cd /var/www/html/custom_apps/upschooling && make'
|
||||||
podman exec --user 33 nextcloud php occ maintenance:install --database sqlite --admin-user admin --admin-pass admin
|
|
||||||
podman exec --user 33 nextcloud php occ config:system:set --value=true --type=boolean debug
|
podman exec --user 33 nextcloud php occ config:system:set --value=true --type=boolean debug
|
||||||
podman exec --user 33 nextcloud php occ app:enable --force upschooling
|
|
||||||
|
|
234
src/App.vue
234
src/App.vue
|
@ -1,234 +0,0 @@
|
||||||
<template>
|
|
||||||
<div id="content" class="app-upschooling">
|
|
||||||
<AppNavigation>
|
|
||||||
<AppNavigationNew v-if="!loading"
|
|
||||||
:text="t('upschooling', 'New note')"
|
|
||||||
:disabled="false"
|
|
||||||
button-id="new-upschooling-button"
|
|
||||||
button-class="icon-add"
|
|
||||||
@click="newNote" />
|
|
||||||
<ul>
|
|
||||||
<AppNavigationItem v-for="note in notes"
|
|
||||||
:key="note.id"
|
|
||||||
:title="note.title ? note.title : t('upschooling', 'New note')"
|
|
||||||
:class="{active: currentNoteId === note.id}"
|
|
||||||
@click="openNote(note)">
|
|
||||||
<template slot="actions">
|
|
||||||
<ActionButton v-if="note.id === -1"
|
|
||||||
icon="icon-close"
|
|
||||||
@click="cancelNewNote(note)">
|
|
||||||
{{ t('upschooling', 'Cancel note creation') }}
|
|
||||||
</ActionButton>
|
|
||||||
<ActionButton v-else
|
|
||||||
icon="icon-delete"
|
|
||||||
@click="deleteNote(note)">
|
|
||||||
{{ t('upschooling', 'Delete note') }}
|
|
||||||
</ActionButton>
|
|
||||||
</template>
|
|
||||||
</AppNavigationItem>
|
|
||||||
</ul>
|
|
||||||
</AppNavigation>
|
|
||||||
<AppContent>
|
|
||||||
<div v-if="currentNote">
|
|
||||||
<input ref="title"
|
|
||||||
v-model="currentNote.title"
|
|
||||||
type="text"
|
|
||||||
:disabled="updating">
|
|
||||||
<textarea ref="content" v-model="currentNote.content" :disabled="updating" />
|
|
||||||
<input type="button"
|
|
||||||
class="primary"
|
|
||||||
:value="t('upschooling', 'Save')"
|
|
||||||
:disabled="updating || !savePossible"
|
|
||||||
@click="saveNote">
|
|
||||||
</div>
|
|
||||||
<div v-else id="emptycontent">
|
|
||||||
<div class="icon-file" />
|
|
||||||
<h2>{{ t('upschooling', 'Create a note to get started') }}</h2>
|
|
||||||
</div>
|
|
||||||
</AppContent>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
|
|
||||||
import AppContent from '@nextcloud/vue/dist/Components/AppContent'
|
|
||||||
import AppNavigation from '@nextcloud/vue/dist/Components/AppNavigation'
|
|
||||||
import AppNavigationItem from '@nextcloud/vue/dist/Components/AppNavigationItem'
|
|
||||||
import AppNavigationNew from '@nextcloud/vue/dist/Components/AppNavigationNew'
|
|
||||||
|
|
||||||
import '@nextcloud/dialogs/styles/toast.scss'
|
|
||||||
import { generateUrl } from '@nextcloud/router'
|
|
||||||
import { showError, showSuccess } from '@nextcloud/dialogs'
|
|
||||||
import axios from '@nextcloud/axios'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'App',
|
|
||||||
components: {
|
|
||||||
ActionButton,
|
|
||||||
AppContent,
|
|
||||||
AppNavigation,
|
|
||||||
AppNavigationItem,
|
|
||||||
AppNavigationNew,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
notes: [],
|
|
||||||
currentNoteId: null,
|
|
||||||
updating: false,
|
|
||||||
loading: true,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
/**
|
|
||||||
* Return the currently selected note object
|
|
||||||
* @returns {Object|null}
|
|
||||||
*/
|
|
||||||
currentNote() {
|
|
||||||
if (this.currentNoteId === null) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return this.notes.find((note) => note.id === this.currentNoteId)
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if a note is selected and its title is not empty
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
savePossible() {
|
|
||||||
return this.currentNote && this.currentNote.title !== ''
|
|
||||||
},
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Fetch list of notes when the component is loaded
|
|
||||||
*/
|
|
||||||
async mounted() {
|
|
||||||
try {
|
|
||||||
const response = await axios.get(generateUrl('/apps/upschooling/notes'))
|
|
||||||
this.notes = response.data
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e)
|
|
||||||
showError(t('upschooling', 'Could not fetch notes'))
|
|
||||||
}
|
|
||||||
this.loading = false
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
/**
|
|
||||||
* Create a new note and focus the note content field automatically
|
|
||||||
* @param {Object} note Note object
|
|
||||||
*/
|
|
||||||
openNote(note) {
|
|
||||||
if (this.updating) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.currentNoteId = note.id
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.content.focus()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Action tiggered when clicking the save button
|
|
||||||
* create a new note or save
|
|
||||||
*/
|
|
||||||
saveNote() {
|
|
||||||
if (this.currentNoteId === -1) {
|
|
||||||
this.createNote(this.currentNote)
|
|
||||||
} else {
|
|
||||||
this.updateNote(this.currentNote)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Create a new note and focus the note content field automatically
|
|
||||||
* The note is not yet saved, therefore an id of -1 is used until it
|
|
||||||
* has been persisted in the backend
|
|
||||||
*/
|
|
||||||
newNote() {
|
|
||||||
if (this.currentNoteId !== -1) {
|
|
||||||
this.currentNoteId = -1
|
|
||||||
this.notes.push({
|
|
||||||
id: -1,
|
|
||||||
title: '',
|
|
||||||
content: '',
|
|
||||||
})
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.title.focus()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Abort creating a new note
|
|
||||||
*/
|
|
||||||
cancelNewNote() {
|
|
||||||
this.notes.splice(this.notes.findIndex((note) => note.id === -1), 1)
|
|
||||||
this.currentNoteId = null
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Create a new note by sending the information to the server
|
|
||||||
* @param {Object} note Note object
|
|
||||||
*/
|
|
||||||
async createNote(note) {
|
|
||||||
this.updating = true
|
|
||||||
try {
|
|
||||||
const response = await axios.post(generateUrl('/apps/upschooling/notes'), note)
|
|
||||||
const index = this.notes.findIndex((match) => match.id === this.currentNoteId)
|
|
||||||
this.$set(this.notes, index, response.data)
|
|
||||||
this.currentNoteId = response.data.id
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e)
|
|
||||||
showError(t('upschooling', 'Could not create the note'))
|
|
||||||
}
|
|
||||||
this.updating = false
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Update an existing note on the server
|
|
||||||
* @param {Object} note Note object
|
|
||||||
*/
|
|
||||||
async updateNote(note) {
|
|
||||||
this.updating = true
|
|
||||||
try {
|
|
||||||
await axios.put(generateUrl(`/apps/upschooling/notes/${note.id}`), note)
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e)
|
|
||||||
showError(t('upschooling', 'Could not update the note'))
|
|
||||||
}
|
|
||||||
this.updating = false
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Delete a note, remove it from the frontend and show a hint
|
|
||||||
* @param {Object} note Note object
|
|
||||||
*/
|
|
||||||
async deleteNote(note) {
|
|
||||||
try {
|
|
||||||
await axios.delete(generateUrl(`/apps/upschooling/notes/${note.id}`))
|
|
||||||
this.notes.splice(this.notes.indexOf(note), 1)
|
|
||||||
if (this.currentNoteId === note.id) {
|
|
||||||
this.currentNoteId = null
|
|
||||||
}
|
|
||||||
showSuccess(t('upschooling', 'Note deleted'))
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e)
|
|
||||||
showError(t('upschooling', 'Could not delete the note'))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style scoped>
|
|
||||||
#app-content > div {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type='text'] {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
flex-grow: 1;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
35
src/main.js
35
src/main.js
|
@ -1,35 +0,0 @@
|
||||||
/**
|
|
||||||
* @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com>
|
|
||||||
*
|
|
||||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
|
||||||
*
|
|
||||||
* @license GNU AGPL version 3 or any later version
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as
|
|
||||||
* published by the Free Software Foundation, either version 3 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
import { generateFilePath } from '@nextcloud/router'
|
|
||||||
|
|
||||||
import Vue from 'vue'
|
|
||||||
import App from './App'
|
|
||||||
|
|
||||||
// eslint-disable-next-line
|
|
||||||
__webpack_public_path__ = generateFilePath(appName, '', 'js/')
|
|
||||||
|
|
||||||
Vue.mixin({ methods: { t, n } })
|
|
||||||
|
|
||||||
export default new Vue({
|
|
||||||
el: '#content',
|
|
||||||
render: h => h(App),
|
|
||||||
})
|
|
|
@ -1,3 +0,0 @@
|
||||||
const stylelintConfig = require('@nextcloud/stylelint-config')
|
|
||||||
|
|
||||||
module.exports = stylelintConfig
|
|
1
templates/content/index.php
Normal file
1
templates/content/index.php
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<h1>Hello world</h1>
|
18
templates/index.php
Normal file
18
templates/index.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
script('upschooling', 'script');
|
||||||
|
style('upschooling', 'style');
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div id="app">
|
||||||
|
<div id="app-navigation">
|
||||||
|
<?php print_unescaped($this->inc('navigation/index')); ?>
|
||||||
|
<?php print_unescaped($this->inc('settings/index')); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="app-content">
|
||||||
|
<div id="app-content-wrapper">
|
||||||
|
<?php print_unescaped($this->inc('content/index')); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
<div id="content"></div>
|
|
10
templates/navigation/index.php
Normal file
10
templates/navigation/index.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<ul>
|
||||||
|
<li><a href="#">First level entry</a></li>
|
||||||
|
<li>
|
||||||
|
<a href="#">First level container</a>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#">Second level entry</a></li>
|
||||||
|
<li><a href="#">Second level entry</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
10
templates/settings/index.php
Normal file
10
templates/settings/index.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<div id="app-settings">
|
||||||
|
<div id="app-settings-header">
|
||||||
|
<button class="settings-button"
|
||||||
|
data-apps-slide-toggle="#app-settings-content"
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div id="app-settings-content">
|
||||||
|
<!-- Your settings in here -->
|
||||||
|
</div>
|
||||||
|
</div>
|
29
tests/Integration/AppTest.php
Normal file
29
tests/Integration/AppTest.php
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OCA\UPschooling\Tests\Integration\Controller;
|
||||||
|
|
||||||
|
use OCP\AppFramework\App;
|
||||||
|
use Test\TestCase;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test shows how to make a small Integration Test. Query your class
|
||||||
|
* directly from the container, only pass in mocks if needed and run your tests
|
||||||
|
* against the database
|
||||||
|
*/
|
||||||
|
class AppTest extends TestCase {
|
||||||
|
|
||||||
|
private $container;
|
||||||
|
|
||||||
|
public function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
$app = new App('upschooling');
|
||||||
|
$this->container = $app->getContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAppInstalled() {
|
||||||
|
$appManager = $this->container->query('OCP\App\IAppManager');
|
||||||
|
$this->assertTrue($appManager->isInstalled('upschooling'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,61 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OCA\UPschooling\Tests\Integration\Controller;
|
|
||||||
|
|
||||||
use OCP\AppFramework\App;
|
|
||||||
use OCP\IRequest;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
|
|
||||||
|
|
||||||
use OCA\UPschooling\Db\Note;
|
|
||||||
use OCA\UPschooling\Db\NoteMapper;
|
|
||||||
use OCA\UPschooling\Controller\NoteController;
|
|
||||||
|
|
||||||
class NoteIntegrationTest extends TestCase {
|
|
||||||
private $controller;
|
|
||||||
private $mapper;
|
|
||||||
private $userId = 'john';
|
|
||||||
|
|
||||||
public function setUp(): void {
|
|
||||||
$app = new App('upschooling');
|
|
||||||
$container = $app->getContainer();
|
|
||||||
|
|
||||||
// only replace the user id
|
|
||||||
$container->registerService('userId', function () {
|
|
||||||
return $this->userId;
|
|
||||||
});
|
|
||||||
|
|
||||||
// we do not care about the request but the controller needs it
|
|
||||||
$container->registerService(IRequest::class, function () {
|
|
||||||
return $this->createMock(IRequest::class);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->controller = $container->query(NoteController::class);
|
|
||||||
$this->mapper = $container->query(NoteMapper::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testUpdate() {
|
|
||||||
// create a new note that should be updated
|
|
||||||
$note = new Note();
|
|
||||||
$note->setTitle('old_title');
|
|
||||||
$note->setContent('old_content');
|
|
||||||
$note->setUserId($this->userId);
|
|
||||||
|
|
||||||
$id = $this->mapper->insert($note)->getId();
|
|
||||||
|
|
||||||
// fromRow does not set the fields as updated
|
|
||||||
$updatedNote = Note::fromRow([
|
|
||||||
'id' => $id,
|
|
||||||
'user_id' => $this->userId
|
|
||||||
]);
|
|
||||||
$updatedNote->setContent('content');
|
|
||||||
$updatedNote->setTitle('title');
|
|
||||||
|
|
||||||
$result = $this->controller->update($id, 'title', 'content');
|
|
||||||
|
|
||||||
$this->assertEquals($updatedNote, $result->getData());
|
|
||||||
|
|
||||||
// clean up
|
|
||||||
$this->mapper->delete($result->getData());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OCA\UPschooling\Tests\Unit\Controller;
|
|
||||||
|
|
||||||
use OCA\UPschooling\Controller\NoteApiController;
|
|
||||||
|
|
||||||
class NoteApiControllerTest extends NoteControllerTest {
|
|
||||||
public function setUp(): void {
|
|
||||||
parent::setUp();
|
|
||||||
$this->controller = new NoteApiController($this->request, $this->service, $this->userId);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OCA\UPschooling\Tests\Unit\Controller;
|
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
|
|
||||||
use OCP\AppFramework\Http;
|
|
||||||
use OCP\IRequest;
|
|
||||||
|
|
||||||
use OCA\UPschooling\Service\NoteNotFound;
|
|
||||||
use OCA\UPschooling\Service\NoteService;
|
|
||||||
use OCA\UPschooling\Controller\NoteController;
|
|
||||||
|
|
||||||
class NoteControllerTest extends TestCase {
|
|
||||||
protected $controller;
|
|
||||||
protected $service;
|
|
||||||
protected $userId = 'john';
|
|
||||||
protected $request;
|
|
||||||
|
|
||||||
public function setUp(): void {
|
|
||||||
$this->request = $this->getMockBuilder(IRequest::class)->getMock();
|
|
||||||
$this->service = $this->getMockBuilder(NoteService::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
$this->controller = new NoteController($this->request, $this->service, $this->userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testUpdate() {
|
|
||||||
$note = 'just check if this value is returned correctly';
|
|
||||||
$this->service->expects($this->once())
|
|
||||||
->method('update')
|
|
||||||
->with($this->equalTo(3),
|
|
||||||
$this->equalTo('title'),
|
|
||||||
$this->equalTo('content'),
|
|
||||||
$this->equalTo($this->userId))
|
|
||||||
->will($this->returnValue($note));
|
|
||||||
|
|
||||||
$result = $this->controller->update(3, 'title', 'content');
|
|
||||||
|
|
||||||
$this->assertEquals($note, $result->getData());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function testUpdateNotFound() {
|
|
||||||
// test the correct status code if no note is found
|
|
||||||
$this->service->expects($this->once())
|
|
||||||
->method('update')
|
|
||||||
->will($this->throwException(new NoteNotFound()));
|
|
||||||
|
|
||||||
$result = $this->controller->update(3, 'title', 'content');
|
|
||||||
|
|
||||||
$this->assertEquals(Http::STATUS_NOT_FOUND, $result->getStatus());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,24 +1,31 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace OCA\UPschooling\Controller;
|
namespace OCA\UPschooling\Tests\Unit\Controller;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit_Framework_TestCase;
|
||||||
|
|
||||||
use OCP\AppFramework\Http\TemplateResponse;
|
use OCP\AppFramework\Http\TemplateResponse;
|
||||||
|
|
||||||
class PageControllerTest extends TestCase {
|
use OCA\UPschooling\Controller\PageController;
|
||||||
|
|
||||||
|
|
||||||
|
class PageControllerTest extends PHPUnit_Framework_TestCase {
|
||||||
private $controller;
|
private $controller;
|
||||||
|
private $userId = 'john';
|
||||||
|
|
||||||
public function setUp(): void {
|
public function setUp() {
|
||||||
$request = $this->getMockBuilder('OCP\IRequest')->getMock();
|
$request = $this->getMockBuilder('OCP\IRequest')->getMock();
|
||||||
$this->controller = new PageController($request);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
$this->controller = new PageController(
|
||||||
|
'upschooling', $request, $this->userId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testIndex() {
|
public function testIndex() {
|
||||||
$result = $this->controller->index();
|
$result = $this->controller->index();
|
||||||
|
|
||||||
$this->assertEquals('main', $result->getTemplateName());
|
$this->assertEquals('index', $result->getTemplateName());
|
||||||
$this->assertTrue($result instanceof TemplateResponse);
|
$this->assertTrue($result instanceof TemplateResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace OCA\UPschooling\Tests\Unit\Service;
|
|
||||||
|
|
||||||
use OCA\UPschooling\Service\NoteNotFound;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
|
|
||||||
use OCP\AppFramework\Db\DoesNotExistException;
|
|
||||||
|
|
||||||
use OCA\UPschooling\Db\Note;
|
|
||||||
use OCA\UPschooling\Service\NoteService;
|
|
||||||
use OCA\UPschooling\Db\NoteMapper;
|
|
||||||
|
|
||||||
class NoteServiceTest extends TestCase {
|
|
||||||
private $service;
|
|
||||||
private $mapper;
|
|
||||||
private $userId = 'john';
|
|
||||||
|
|
||||||
public function setUp(): void {
|
|
||||||
$this->mapper = $this->getMockBuilder(NoteMapper::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
$this->service = new NoteService($this->mapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testUpdate() {
|
|
||||||
// the existing note
|
|
||||||
$note = Note::fromRow([
|
|
||||||
'id' => 3,
|
|
||||||
'title' => 'yo',
|
|
||||||
'content' => 'nope'
|
|
||||||
]);
|
|
||||||
$this->mapper->expects($this->once())
|
|
||||||
->method('find')
|
|
||||||
->with($this->equalTo(3))
|
|
||||||
->will($this->returnValue($note));
|
|
||||||
|
|
||||||
// the note when updated
|
|
||||||
$updatedNote = Note::fromRow(['id' => 3]);
|
|
||||||
$updatedNote->setTitle('title');
|
|
||||||
$updatedNote->setContent('content');
|
|
||||||
$this->mapper->expects($this->once())
|
|
||||||
->method('update')
|
|
||||||
->with($this->equalTo($updatedNote))
|
|
||||||
->will($this->returnValue($updatedNote));
|
|
||||||
|
|
||||||
$result = $this->service->update(3, 'title', 'content', $this->userId);
|
|
||||||
|
|
||||||
$this->assertEquals($updatedNote, $result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testUpdateNotFound() {
|
|
||||||
$this->expectException(NoteNotFound::class);
|
|
||||||
// test the correct status code if no note is found
|
|
||||||
$this->mapper->expects($this->once())
|
|
||||||
->method('find')
|
|
||||||
->with($this->equalTo(3))
|
|
||||||
->will($this->throwException(new DoesNotExistException('')));
|
|
||||||
|
|
||||||
$this->service->update(3, 'title', 'content', $this->userId);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +1,19 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once __DIR__ . '/../../../tests/bootstrap.php';
|
if (!defined('PHPUNIT_RUN')) {
|
||||||
|
define('PHPUNIT_RUN', 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once __DIR__.'/../../../lib/base.php';
|
||||||
|
|
||||||
|
// Fix for "Autoload path not allowed: .../tests/lib/testcase.php"
|
||||||
|
\OC::$loader->addValidRoot(OC::$SERVERROOT . '/tests');
|
||||||
|
|
||||||
|
// Fix for "Autoload path not allowed: .../upschooling/tests/testcase.php"
|
||||||
|
\OC_App::loadApp('upschooling');
|
||||||
|
|
||||||
|
if(!class_exists('PHPUnit_Framework_TestCase')) {
|
||||||
|
require_once('PHPUnit/Autoload.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
OC_Hook::clear();
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
const webpackConfig = require('@nextcloud/webpack-vue-config')
|
|
||||||
|
|
||||||
module.exports = webpackConfig
|
|
Loading…
Reference in a new issue