Adapt react-client to use the real backend API (#1545)

Co-authored-by: Philip Molares <philip.molares@udo.edu>
Co-authored-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Erik Michelson 2022-04-15 23:03:15 +02:00 committed by GitHub
parent 3399ed2023
commit 26f90505ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
227 changed files with 4726 additions and 2310 deletions

View file

@ -4,14 +4,16 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { testNoteId } from '../support/visit-test-editor'
describe('Delete note', () => {
beforeEach(() => {
cy.visitTestNote()
})
it('correctly deletes a note', () => {
cy.intercept('DELETE', '/mock-backend/api/private/notes/mock_note_id', {
statusCode: 200
cy.intercept('DELETE', `/api/mock-backend/private/notes/${testNoteId}`, {
statusCode: 204
})
cy.getByCypressId('sidebar.deleteNote.button').click()
cy.getByCypressId('sidebar.deleteNote.modal').should('be.visible')

View file

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
@ -16,13 +16,13 @@ describe('File upload', () => {
beforeEach(() => {
cy.intercept(
{
method: 'GET',
url: '/mock-backend/api/private/media/upload-post'
method: 'POST',
url: '/api/mock-backend/private/media'
},
{
statusCode: 200,
statusCode: 201,
body: {
link: imageUrl
url: imageUrl
}
}
)
@ -69,8 +69,8 @@ describe('File upload', () => {
it('fails', () => {
cy.intercept(
{
method: 'GET',
url: '/mock-backend/api/private/media/upload-post'
method: 'POST',
url: '/api/mock-backend/private/media'
},
{
statusCode: 400

View file

@ -24,7 +24,7 @@ describe('History', () => {
describe('is as given when not empty', () => {
beforeEach(() => {
cy.clearLocalStorage('history')
cy.intercept('GET', '/mock-backend/api/private/me/history', {
cy.intercept('GET', '/api/mock-backend/private/me/history', {
body: [
{
identifier: 'cypress',
@ -51,7 +51,7 @@ describe('History', () => {
describe('is untitled when not empty', () => {
beforeEach(() => {
cy.clearLocalStorage('history')
cy.intercept('GET', '/mock-backend/api/private/me/history', {
cy.intercept('GET', '/api/mock-backend/private/me/history', {
body: [
{
identifier: 'cypress-no-title',
@ -84,7 +84,7 @@ describe('History', () => {
describe('working', () => {
beforeEach(() => {
cy.intercept('PUT', '/mock-backend/api/private/me/history/features', (req) => {
cy.intercept('PUT', '/api/mock-backend/private/me/history/features', (req) => {
req.reply(200, req.body)
})
})
@ -106,7 +106,7 @@ describe('History', () => {
describe('failing', () => {
beforeEach(() => {
cy.intercept('PUT', '/mock-backend/api/private/me/history/features', {
cy.intercept('PUT', '/api/mock-backend/private/me/history/features', {
statusCode: 401
})
})
@ -128,7 +128,7 @@ describe('History', () => {
describe('Import', () => {
beforeEach(() => {
cy.clearLocalStorage('history')
cy.intercept('GET', '/mock-backend/api/private/me/history', {
cy.intercept('GET', '/api/mock-backend/private/me/history', {
body: []
})
cy.visitHistory()

View file

@ -7,7 +7,7 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */
describe('Intro page', () => {
beforeEach(() => {
cy.intercept('/mock-backend/public/intro.md', 'test content')
cy.intercept('/mock-public/intro.md', 'test content')
cy.visitHome()
})
@ -17,7 +17,7 @@ describe('Intro page', () => {
})
it("won't show anything if no content was found", () => {
cy.intercept('/mock-backend/public/intro.md', {
cy.intercept('/mock-public/intro.md', {
statusCode: 404
})
cy.visitHome()

View file

@ -11,13 +11,13 @@ const motdMockHtml = 'This is the <strong>mock</strong> Motd call'
describe('Motd', () => {
const mockExistingMotd = (useEtag?: boolean, content = motdMockContent) => {
cy.intercept('GET', '/mock-backend/public/motd.md', {
cy.intercept('GET', '/mock-public/motd.md', {
statusCode: 200,
headers: { [useEtag ? 'etag' : 'Last-Modified']: MOCK_LAST_MODIFIED },
body: content
})
cy.intercept('HEAD', '/mock-backend/public/motd.md', {
cy.intercept('HEAD', '/mock-public/motd.md', {
statusCode: 200,
headers: { [useEtag ? 'etag' : 'Last-Modified']: MOCK_LAST_MODIFIED }
})

View file

@ -8,7 +8,7 @@ describe('profile page', () => {
beforeEach(() => {
cy.intercept(
{
url: '/mock-backend/api/private/tokens',
url: '/api/mock-backend/private/tokens',
method: 'GET'
},
{
@ -25,7 +25,7 @@ describe('profile page', () => {
)
cy.intercept(
{
url: '/mock-backend/api/private/tokens',
url: '/api/mock-backend/private/tokens',
method: 'POST'
},
{
@ -36,16 +36,18 @@ describe('profile page', () => {
createdAt: '2021-11-21T01:11:12+01:00',
lastUsed: '2021-11-21T01:11:12+01:00',
validUntil: '2023-11-21'
}
},
statusCode: 201
}
)
cy.intercept(
{
url: '/mock-backend/api/private/tokens/cypress',
url: '/api/mock-backend/private/tokens/cypress',
method: 'DELETE'
},
{
body: []
body: [],
statusCode: 204
}
)
cy.visit('/profile', { retryOnNetworkFailure: true })

View file

@ -4,28 +4,12 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
const authProvidersDisabled = {
facebook: false,
github: false,
twitter: false,
gitlab: false,
dropbox: false,
ldap: false,
google: false,
saml: false,
oauth2: false,
local: false
}
import type { AuthProvider } from '../../src/api/config/types'
import { AuthProviderType } from '../../src/api/config/types'
const initLoggedOutTestWithCustomAuthProviders = (
cy: Cypress.cy,
enabledProviders: Partial<typeof authProvidersDisabled>
) => {
const initLoggedOutTestWithCustomAuthProviders = (cy: Cypress.cy, enabledProviders: AuthProvider[]) => {
cy.loadConfig({
authProviders: {
...authProvidersDisabled,
...enabledProviders
}
authProviders: enabledProviders
})
cy.visitHome()
cy.logout()
@ -41,55 +25,71 @@ describe('When logged-in, ', () => {
describe('When logged-out ', () => {
describe('and no auth-provider is enabled, ', () => {
it('sign-in button is hidden', () => {
initLoggedOutTestWithCustomAuthProviders(cy, {})
initLoggedOutTestWithCustomAuthProviders(cy, [])
cy.getByCypressId('sign-in-button').should('not.exist')
})
})
describe('and an interactive auth-provider is enabled, ', () => {
it('sign-in button points to login route: internal', () => {
initLoggedOutTestWithCustomAuthProviders(cy, {
local: true
})
initLoggedOutTestWithCustomAuthProviders(cy, [
{
type: AuthProviderType.LOCAL
}
])
cy.getByCypressId('sign-in-button').should('be.visible').should('have.attr', 'href', '/login')
})
it('sign-in button points to login route: ldap', () => {
initLoggedOutTestWithCustomAuthProviders(cy, {
ldap: true
})
initLoggedOutTestWithCustomAuthProviders(cy, [
{
type: AuthProviderType.LDAP,
identifier: 'cy-ldap',
providerName: 'cy LDAP'
}
])
cy.getByCypressId('sign-in-button').should('be.visible').should('have.attr', 'href', '/login')
})
})
describe('and only one one-click auth-provider is enabled, ', () => {
it('sign-in button points to auth-provider', () => {
initLoggedOutTestWithCustomAuthProviders(cy, {
saml: true
})
initLoggedOutTestWithCustomAuthProviders(cy, [
{
type: AuthProviderType.GITHUB
}
])
cy.getByCypressId('sign-in-button')
.should('be.visible')
// The absolute URL is used because it is defined as API base URL absolute.
.should('have.attr', 'href', '/mock-backend/auth/saml')
.should('have.attr', 'href', '/auth/github')
})
})
describe('and multiple one-click auth-providers are enabled, ', () => {
it('sign-in button points to login route', () => {
initLoggedOutTestWithCustomAuthProviders(cy, {
saml: true,
github: true
})
initLoggedOutTestWithCustomAuthProviders(cy, [
{
type: AuthProviderType.GITHUB
},
{
type: AuthProviderType.GOOGLE
}
])
cy.getByCypressId('sign-in-button').should('be.visible').should('have.attr', 'href', '/login')
})
})
describe('and one-click- as well as interactive auth-providers are enabled, ', () => {
it('sign-in button points to login route', () => {
initLoggedOutTestWithCustomAuthProviders(cy, {
saml: true,
local: true
})
initLoggedOutTestWithCustomAuthProviders(cy, [
{
type: AuthProviderType.GITHUB
},
{
type: AuthProviderType.LOCAL
}
])
cy.getByCypressId('sign-in-button').should('be.visible').should('have.attr', 'href', '/login')
})
})

View file

@ -4,6 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { AuthProviderType } from '../../src/api/config/types'
declare namespace Cypress {
interface Chainable {
loadConfig(): Chainable<Window>
@ -12,43 +14,70 @@ declare namespace Cypress {
export const branding = {
name: 'DEMO Corp',
logo: '/mock-backend/public/img/demo.png'
logo: '/mock-public/img/demo.png'
}
export const authProviders = {
facebook: true,
github: true,
twitter: true,
gitlab: true,
dropbox: true,
ldap: true,
google: true,
saml: true,
oauth2: true,
local: true
}
export const authProviders = [
{
type: AuthProviderType.FACEBOOK
},
{
type: AuthProviderType.GITHUB
},
{
type: AuthProviderType.TWITTER
},
{
type: AuthProviderType.DROPBOX
},
{
type: AuthProviderType.GOOGLE
},
{
type: AuthProviderType.LOCAL
},
{
type: AuthProviderType.LDAP,
identifier: 'test-ldap',
providerName: 'Test LDAP'
},
{
type: AuthProviderType.OAUTH2,
identifier: 'test-oauth2',
providerName: 'Test OAuth2'
},
{
type: AuthProviderType.SAML,
identifier: 'test-saml',
providerName: 'Test SAML'
},
{
type: AuthProviderType.GITLAB,
identifier: 'test-gitlab',
providerName: 'Test GitLab'
}
]
export const config = {
allowAnonymous: true,
allowRegister: true,
authProviders: authProviders,
branding: branding,
customAuthNames: {
ldap: 'FooBar',
oauth2: 'Olaf2',
saml: 'aufSAMLn.de'
},
maxDocumentLength: 200,
useImageProxy: false,
specialUrls: {
privacy: 'https://example.com/privacy',
termsOfUse: 'https://example.com/termsOfUse',
imprint: 'https://example.com/imprint'
},
plantumlServer: 'http://mock-plantuml.local',
version: {
version: 'mock',
sourceCodeUrl: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
issueTrackerUrl: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
major: 0,
minor: 0,
patch: 0,
preRelease: '',
commit: 'MOCK'
},
plantumlServer: 'http://mock-plantuml.local',
maxDocumentLength: 200,
iframeCommunication: {
editorOrigin: 'http://127.0.0.1:3001/',
rendererOrigin: 'http://127.0.0.1:3001/'
@ -56,7 +85,7 @@ export const config = {
}
Cypress.Commands.add('loadConfig', (additionalConfig?: Partial<typeof config>) => {
return cy.intercept('/mock-backend/api/private/config', {
return cy.intercept('/api/mock-backend/private/config', {
statusCode: 200,
body: {
...config,
@ -68,11 +97,11 @@ Cypress.Commands.add('loadConfig', (additionalConfig?: Partial<typeof config>) =
beforeEach(() => {
cy.loadConfig()
cy.intercept('GET', '/mock-backend/public/motd.md', {
cy.intercept('GET', '/mock-public/motd.md', {
body: '404 Not Found!',
statusCode: 404
})
cy.intercept('HEAD', '/mock-backend/public/motd.md', {
cy.intercept('HEAD', '/mock-public/motd.md', {
statusCode: 404
})
})

View file

@ -25,6 +25,6 @@ import './config'
import './fill'
import './get-by-id'
import './get-iframe-content'
import './login'
import './logout'
import './visit-test-editor'
import './visit'

View file

@ -3,26 +3,30 @@
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
export const testNoteId = 'test'
beforeEach(() => {
cy.intercept(`/mock-backend/api/private/notes/${testNoteId}-get`, {
cy.intercept(`/api/mock-backend/private/notes/${testNoteId}`, {
content: '',
metadata: {
id: 'mock_note_id',
alias: 'mockNote',
version: 2,
viewCount: 0,
id: testNoteId,
alias: ['mock-note'],
primaryAlias: 'mock-note',
title: 'Mock Note',
description: 'Mocked note for testing',
tags: ['test', 'mock', 'cypress'],
updateTime: '2021-04-24T09:27:51.000Z',
updateUser: {
userName: 'test',
displayName: 'Testy',
photo: '',
email: ''
},
updateUser: null,
viewCount: 0,
version: 2,
createTime: '2021-04-24T09:27:51.000Z',
editedBy: []
}
editedBy: [],
permissions: {
owner: null,
sharedToUsers: [],
sharedToGroups: []
}
},
editedByAtPosition: []
})
})