Unverified Commit feec789d authored by torgiren's avatar torgiren
Browse files

feature: migrate to ingresses instead of api-gateway - closes #454

Signed-off-by: torgiren's avatarMarcin Fabrykowski <git@fabrykowski.pl>
1 merge request!45feature: migrate to ingresses instead of api-gateway - closes #454
Pipeline #2930 passed with stages
in 6 minutes and 25 seconds
Showing with 435 additions and 472 deletions
+435 -472
......@@ -135,13 +135,13 @@ deploy branch:
helm upgrade -n $KUBE_NAMESPACE -i test-controller exphost/exphost-controller -f gitlab-ci-values.yml
--version v0.0.0-latest
--set global.domain=${KUBE_NAMESPACE}.ci.exphost.pl
--wait --wait-for-jobs
--wait --wait-for-jobs --skip-crds
- >
helm upgrade -n $KUBE_NAMESPACE -i test-webui chart -f gitlab-ci-values-webui.yml
--set podAnnotations."app\.gitlab\.com/app"=$CI_PROJECT_PATH_SLUG
--set podAnnotations."app\.gitlab\.com/env"=$CI_ENVIRONMENT_SLUG
--set global.domain=${KUBE_NAMESPACE}.ci.exphost.pl
--wait --wait-for-jobs
--wait --wait-for-jobs --skip-crds
- kubectl -n $KUBE_NAMESPACE rollout restart deployment test-webui-controller-webui
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
......
module.exports = {
settings: {
"react": {
"version": "detect"
}
},
env: {
browser: true,
es2021: true,
......
......@@ -16,14 +16,12 @@
"history": "^5.3.0",
"jest": "^27.5.1",
"jest-junit": "^13.0.0",
"nock": "^13.2.4",
"nock": "^13.3.4",
"react": "^17.0.2",
"react-bootstrap": "^2.4.0",
"react-cookie": "^4.1.1",
"react-dom": "^17.0.2",
"react-router-dom": "^6.2.1",
"react-scripts": "5.0.0",
"storybook": "^6.4.19",
"web-vitals": "^2.1.2"
},
"scripts": {
......
......@@ -10,51 +10,42 @@ function AppDomainAdd (props) {
event.preventDefault()
const fields = [['name', 'name']]
for (let i = 0; i < fields.length; i++) {
console.log(input[fields[i][0]])
if (input[fields[i][0]] == null || input[fields[i][0]] === '') {
// alert("Field "+fields[i][1]+" cannot be empty");
setMessage('no field ' + fields[i][1])
return 2
}
}
const values = `name: "${input.name}",
org: "${props.org}"`
const query = JSON.stringify({
query: `mutation {
domainRegister(${values})
{
domain {
name,
org,
},
error
}
}`
})
const values = {
name: input.name,
org: props.org
}
const requestOptions = {
url: window.API_URL + '/graphql',
url: window.API_URL + '/api/domains/v1/domains',
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: query,
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('access_token')
},
data: values,
responseType: 'json'
}
axios
.request(requestOptions)
.then(function (response) {
const res = response.data // Response received from the API
if (res.data.domainRegister.error &&
res.data.domainRegister.error.includes('already exists')) {
setMessage('error 1: already exists')
return 1
}
if (res.data.domainRegister.error) {
setMessage('error 2: submit failed')
return 2
}
setMessage('added')
return 0
})
.catch(function (err) {
if (err.response) {
if (err.response.status === 409) {
setMessage('error 1: already exists')
return 1
}
console.log(err)
setMessage('error 2: submit failed')
return 2
}
console.log(err)
setMessage('error 3: submit error')
// alert("Submit failed")
......
......@@ -3,6 +3,23 @@ import { render, screen, waitFor, fireEvent } from '@testing-library/react'
import AppDomainAdd from './appDomainAdd'
import nock from 'nock'
beforeEach(() => {
nock.cleanAll()
nock('http://localhost:8080')
.defaultReplyHeaders({
'access-control-allow-origin': '*',
'access-control-allow-credentials': 'true',
'access-control-allow-headers': 'Authorization'
})
.persist()
.intercept('/api/domains/v1/domains', 'OPTIONS')
.query(true)
.reply(200, null)
.post('/api/domains/v1/domains')
.query(true)
.reply(201)
})
test('show apps in console page', () => {
render(<AppDomainAdd org="test-org"/>)
expect(screen.queryByText(/name/i)).toBeInTheDocument()
......@@ -10,33 +27,27 @@ test('show apps in console page', () => {
test('submit domain app wrong response', async () => {
window.API_URL = 'http://localhost:8080'
nock.cleanAll()
nock('http://localhost:8080')
.post('/graphql')
.reply(400, {
}, {
'Access-Control-Allow-Origin': '*',
'Content-type': 'application/json'
.defaultReplyHeaders({
'access-control-allow-origin': '*',
'access-control-allow-credentials': 'true',
'access-control-allow-headers': 'Authorization'
})
.persist()
.intercept('/api/domains/v1/domains', 'OPTIONS')
.query(true)
.reply(200, null)
.post('/api/domains/v1/domains')
.reply(400)
render(<AppDomainAdd org="test-org"/>)
fireEvent.change(screen.getByTestId('domain-add-name'), { target: { value: 'test-aa' } })
fireEvent.click(screen.getByText('Create'))
await waitFor(() => expect(screen.getByTestId('domain-add-message')).toHaveTextContent('submit error'))
await waitFor(() => expect(screen.getByTestId('domain-add-message')).toHaveTextContent('submit failed'))
})
test('submit domain', async () => {
window.API_URL = 'http://localhost:8080'
nock('http://localhost:8080')
.post('/graphql')
.reply(200, {
data: {
domainRegister: {
error: ''
}
}
}, {
'Access-Control-Allow-Origin': '*',
'Content-type': 'application/json'
})
render(<AppDomainAdd org="qwe"/>)
expect(screen.getByTestId('domain-add-org')).toHaveDisplayValue('qwe')
fireEvent.change(screen.getByTestId('domain-add-name'), { target: { value: 'test-aa' } })
......@@ -46,18 +57,20 @@ test('submit domain', async () => {
test('submit app duplicate', async () => {
window.API_URL = 'http://localhost:8080'
nock.cleanAll()
nock('http://localhost:8080')
.post('/graphql')
.reply(200, {
data: {
domainRegister: {
error: 'App already exists'
}
}
}, {
'Access-Control-Allow-Origin': '*',
'Content-type': 'application/json'
.defaultReplyHeaders({
'access-control-allow-origin': '*',
'access-control-allow-credentials': 'true',
'access-control-allow-headers': 'Authorization'
})
.persist()
.intercept('/api/domains/v1/domains', 'OPTIONS')
.query(true)
.reply(200, null)
.post('/api/domains/v1/domains')
.query(true)
.reply(409)
render(<AppDomainAdd org="test-org"/>)
fireEvent.change(screen.getByTestId('domain-add-name'), { target: { value: 'test-aa' } })
fireEvent.click(screen.getByText('Create'))
......
......@@ -29,29 +29,22 @@ function AppDomainList (props) {
makeTable(apps)
}
function loadApps () {
const query = JSON.stringify({
query: `{
domain(org: "${props.org}") {
domains {
name,
org,
},
error
}
}`
})
const requestOptions = {
url: window.API_URL + '/graphql',
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: query,
url: window.API_URL + '/api/domains/v1/domains',
params: {
org: props.org
},
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + window.localStorage.getItem('access_token')
},
responseType: 'json'
}
axios
.request(requestOptions)
.then(function (response) {
const res = response.data // Response received from the API
makeTable(res.data.domain.domains)
makeTable(response.data)
return 0
})
.catch(function (err) {
......
......@@ -3,29 +3,32 @@ import { render, screen, waitFor } from '@testing-library/react'
import AppDomainList from './appDomainList'
import nock from 'nock'
test('list domains', async () => {
beforeEach(() => {
nock('http://localhost:8080')
.post('/graphql')
.reply(200, {
data: {
domain: {
domains: [
{
name: 'example.com',
org: 'test-org'
},
{
name: 'example2.com',
org: 'test-org'
}
]
}
}
}, {
'Access-Control-Allow-Origin': '*',
'Content-type': 'application/json'
.defaultReplyHeaders({
'access-control-allow-origin': '*',
'access-control-allow-credentials': 'true',
'access-control-allow-headers': 'Authorization'
})
.persist()
.intercept('/api/domains/v1/domains', 'OPTIONS')
.query(true)
.reply(200, null)
.get('/api/domains/v1/domains')
.query(true)
.reply(200, [
{
name: 'example.com',
org: 'test-org'
},
{
name: 'example2.com',
org: 'test-org'
}
])
})
test('list domains', async () => {
window.API_URL = 'http://localhost:8080'
render(<AppDomainList org='test-org'/>)
await waitFor(() => expect(screen.getByText('example.com')).toBeInTheDocument)
......
......@@ -10,58 +10,46 @@ function AppEmailAdd (props) {
event.preventDefault()
const fields = [['mail', 'Mail'], ['cn', 'Name'], ['sn', 'Surname']]
for (let i = 0; i < fields.length; i++) {
console.log(input[fields[i][0]])
if (input[fields[i][0]] == null || input[fields[i][0]] === '') {
// alert("Field "+fields[i][1]+" cannot be empty");
setMessage('no field ' + fields[i][1])
return 2
}
}
const values = `mail: "${input.mail}",
org: "${props.org}",
cn: "${input.cn}",
sn: "${input.sn}"`
const query = JSON.stringify({
query: `mutation {
emailCreate(${values})
{
email {
mail,
sn,
cn,
aliases,
password
},
error
}
}`
})
const values = {
mail: input.mail,
cn: input.cn,
sn: input.sn
}
const requestOptions = {
url: window.API_URL + '/graphql',
url: window.API_URL + '/api/users/v1/emails/?org=' + props.org,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: query,
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('access_token')
},
data: values,
responseType: 'json'
}
axios
.request(requestOptions)
.then(function (response) {
const res = response.data // Response received from the API
if (res.data.emailCreate.error &&
res.data.emailCreate.error.includes('already exists')) {
setMessage('error 1: already exists')
return 1
}
if (res.data.emailCreate.error) {
setMessage('error 2: submit failed')
return 2
}
setMessage('added. password: ' + res.data.emailCreate.email.password)
setMessage('added ' + response.data.password)
return 0
})
.catch(function (err) {
if (err.response) {
if (err.response.status === 409) {
setMessage('error 1: duplicate')
return 1
// alert("Duplicate entry")
}
setMessage('error 2: submit failed')
return 2
}
console.log(err)
setMessage('error 3: submit error')
return 3
// alert("Submit failed")
})
setMessage('adding...')
......
......@@ -3,6 +3,25 @@ import { render, screen, waitFor, fireEvent } from '@testing-library/react'
import AppEmailAdd from './appEmailAdd'
import nock from 'nock'
beforeEach(() => {
nock.cleanAll()
nock('http://localhost:8080')
.defaultReplyHeaders({
'access-control-allow-origin': '*',
'access-control-allow-credentials': 'true',
'access-control-allow-headers': 'Authorization'
})
.persist()
.intercept('/api/users/v1/emails/', 'OPTIONS')
.query(true)
.reply(200, null)
.post('/api/users/v1/emails/')
.query(true)
.reply(201, {
password: 'pass123'
})
})
test('show apps in console page', () => {
render(<AppEmailAdd org="test-org"/>)
expect(screen.queryByText(/Email:/)).toBeInTheDocument()
......@@ -12,13 +31,19 @@ test('show apps in console page', () => {
test('submit email app wrong response', async () => {
window.API_URL = 'http://localhost:8080'
nock.cleanAll()
nock('http://localhost:8080')
.post('/graphql')
.reply(400, {
}, {
'Access-Control-Allow-Origin': '*',
'Content-type': 'application/json'
.defaultReplyHeaders({
'access-control-allow-origin': '*',
'access-control-allow-credentials': 'true',
'access-control-allow-headers': 'Authorization'
})
.persist()
.intercept('/api/users/v1/emails/', 'OPTIONS')
.query(true)
.reply(200, null)
.post('/api/users/v1/emails/')
.reply(400)
render(<AppEmailAdd org="test-org"/>)
fireEvent.change(screen.getByTestId('email-add-mail'), { target: { value: 'test-aa' } })
fireEvent.change(screen.getByTestId('email-add-cn'), { target: { value: 'test-aa' } })
......@@ -29,24 +54,6 @@ test('submit email app wrong response', async () => {
test('submit email', async () => {
window.API_URL = 'http://localhost:8080'
nock('http://localhost:8080')
.post('/graphql')
.reply(200, {
data: {
emailCreate: {
email: {
mail: 'aa@aa.com',
cn: 'John',
sn: 'Brown',
password: 'pass123'
},
error: ''
}
}
}, {
'Access-Control-Allow-Origin': '*',
'Content-type': 'application/json'
})
render(<AppEmailAdd org="qwe"/>)
expect(screen.getByTestId('email-add-org')).toHaveDisplayValue('qwe')
fireEvent.change(screen.getByTestId('email-add-mail'), { target: { value: 'test-aa' } })
......
......@@ -41,31 +41,19 @@ function AppEmailList (props) {
makeTable(emails)
}
function loadEmails () {
const query = JSON.stringify({
query: `{
email(org: "${props.org}") {
emails {
mail,
cn,
sn,
aliases
},
error
}
}`
})
const requestOptions = {
url: window.API_URL + '/graphql',
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: query,
url: window.API_URL + '/api/users/v1/emails/?org=' + props.org,
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('access_token')
},
responseType: 'json'
}
axios
.request(requestOptions)
.then(function (response) {
const res = response.data // Response received from the API
makeTable(res.data.email.emails)
makeTable(response.data.emails)
return 0
})
.catch(function (err) {
......
......@@ -3,39 +3,45 @@ import { render, screen, waitFor } from '@testing-library/react'
import AppEmailList from './appEmailList'
import nock from 'nock'
test('list emails', async () => {
beforeEach(() => {
nock.cleanAll()
nock('http://localhost:8080')
.post('/graphql')
.defaultReplyHeaders({
'access-control-allow-origin': '*',
'access-control-allow-credentials': 'true',
'access-control-allow-headers': 'Authorization'
})
.persist()
.intercept('/api/users/v1/emails/', 'OPTIONS')
.query(true)
.reply(200, null)
.get('/api/users/v1/emails/')
.query(true)
.reply(200, {
data: {
email: {
emails: [
{
mail: 'aa@example.com',
cn: 'Jan',
sn: 'Barski',
aliases: [
'aa@example.com',
'bb@example.com'
]
},
{
mail: 'john@snow.com',
cn: 'John',
sn: 'Snow',
aliases: [
'john@snow.com',
'winter@iscomming.com'
]
}
emails: [
{
mail: 'aa@example.com',
cn: 'Jan',
sn: 'Barski',
aliases: [
'aa@example.com',
'bb@example.com'
]
},
{
mail: 'john@snow.com',
cn: 'John',
sn: 'Snow',
aliases: [
'john@snow.com',
'winter@iscomming.com'
]
}
}
}, {
'Access-Control-Allow-Origin': '*',
'Content-type': 'application/json'
]
})
})
test('list emails', async () => {
window.API_URL = 'http://localhost:8080'
render(<AppEmailList org='test-org'/>)
await waitFor(() => expect(screen.getAllByText('aa@example.com')).toBeInTheDocument)
......
......@@ -10,64 +10,54 @@ function AppNginxAdd (props) {
event.preventDefault()
const fields = [['name', 'name']]
for (let i = 0; i < fields.length; i++) {
console.log(input[fields[i][0]])
if (input[fields[i][0]] == null || input[fields[i][0]] === '') {
// alert("Field "+fields[i][1]+" cannot be empty");
setMessage('no field ' + fields[i][1])
return 2
}
}
let values = `name: "${input.name}",
org: "${props.org}"`
const values = {
org: props.org,
app: 'todo',
name: input.name
}
if (input.gitrepo) {
let valuesGit = `repo: "${input.gitrepo}"`
values.config.git.repo = input.gitrepo
if (input.gitbranch) {
valuesGit += `,branch: "${input.gitbranch}"`
values.config.git.branch = input.gitbranch
}
values += `,git: {${valuesGit}}`
}
if (input.fqdn) {
values += `,fqdns: ["${input.fqdn}"]`
values.config.fqdns = [input.fqdn]
}
const query = JSON.stringify({
query: `mutation {
appNginxCreate(${values})
{
nginx {
name,
org,
fqdns,
},
error
}
}`
})
const requestOptions = {
url: window.API_URL + '/graphql',
url: window.API_URL + '/api/apps/v1/nginx/',
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: query,
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('access_token')
},
data: values,
responseType: 'json'
}
axios
.request(requestOptions)
.then(function (response) {
const res = response.data // Response received from the API
if (res.data.appNginxCreate.error &&
res.data.appNginxCreate.error.includes('already exists')) {
setMessage('error 1: already exists')
return 1
}
if (res.data.appNginxCreate.error) {
setMessage('error 2: submit failed')
return 2
}
setMessage('added')
return 0
})
.catch(function (err) {
if (err.response) {
if (err.response.status === 409) {
setMessage('error 1: already exists')
return 1
}
setMessage('error 2: submit failed')
return 2
}
console.log(err)
setMessage('error 3: submit error')
return 3
// alert("Submit failed")
})
setMessage('adding...')
......
......@@ -2,6 +2,19 @@ import React from 'react'
import { render, screen, waitFor, fireEvent } from '@testing-library/react'
import AppNginxAdd from './appNginxAdd'
import nock from 'nock'
beforeEach(() => {
nock('http://localhost:8080')
.defaultReplyHeaders({
'access-control-allow-origin': '*',
'access-control-allow-credentials': 'true',
'access-control-allow-headers': 'Authorization'
})
.persist()
.intercept('/api/apps/v1/nginx/', 'OPTIONS')
.reply(200, null)
.post('/api/apps/v1/nginx/')
.reply(201)
})
test('show apps in console page', () => {
render(<AppNginxAdd org="test-org"/>)
......@@ -14,13 +27,18 @@ test('show apps in console page', () => {
test('submit nginx app wrong response', async () => {
window.API_URL = 'http://localhost:8080'
nock.cleanAll()
nock('http://localhost:8080')
.post('/graphql')
.reply(400, {
}, {
'Access-Control-Allow-Origin': '*',
'Content-type': 'application/json'
.defaultReplyHeaders({
'access-control-allow-origin': '*',
'access-control-allow-credentials': 'true',
'access-control-allow-headers': 'Authorization'
})
.persist()
.intercept('/api/apps/v1/nginx', 'OPTIONS')
.reply(200, null)
.post('/api/apps/v1/nginx')
.reply(400)
render(<AppNginxAdd org="test-org"/>)
fireEvent.change(screen.getByTestId('nginx-add-name'), { target: { value: 'test-aa' } })
fireEvent.click(screen.getByText('Create'))
......@@ -29,18 +47,6 @@ test('submit nginx app wrong response', async () => {
test('submit nginx app', async () => {
window.API_URL = 'http://localhost:8080'
nock('http://localhost:8080')
.post('/graphql')
.reply(200, {
data: {
appNginxCreate: {
error: ''
}
}
}, {
'Access-Control-Allow-Origin': '*',
'Content-type': 'application/json'
})
render(<AppNginxAdd org="qwe"/>)
expect(screen.getByTestId('nginx-add-org')).toHaveDisplayValue('qwe')
fireEvent.change(screen.getByTestId('nginx-add-name'), { target: { value: 'test-aa' } })
......@@ -50,18 +56,18 @@ test('submit nginx app', async () => {
test('submit nginx app duplicate', async () => {
window.API_URL = 'http://localhost:8080'
nock.cleanAll()
nock('http://localhost:8080')
.post('/graphql')
.reply(200, {
data: {
appNginxCreate: {
error: 'App already exists'
}
}
}, {
'Access-Control-Allow-Origin': '*',
'Content-type': 'application/json'
.defaultReplyHeaders({
'access-control-allow-origin': '*',
'access-control-allow-credentials': 'true',
'access-control-allow-headers': 'Authorization'
})
.persist()
.intercept('/api/apps/v1/nginx/', 'OPTIONS')
.reply(200, null)
.post('/api/apps/v1/nginx/')
.reply(409)
render(<AppNginxAdd org="test-org"/>)
fireEvent.change(screen.getByTestId('nginx-add-name'), { target: { value: 'test-aa' } })
fireEvent.click(screen.getByText('Create'))
......
......@@ -13,14 +13,14 @@ function AppNginxList (props) {
<td>{ app.name }</td>
<td>{ app.org }</td>
<td>
{ app.fqdns
{ app.config?.fqdns
? <ul>
{ app.fqdns.map((fqdn, index) => <li key={index}> <a href={'https://' + fqdn} target="_blank" rel="noopener noreferrer">{ fqdn }</a></li>)}
{ app.config.fqdns.map((fqdn, index) => <li key={index}> <a href={'https://' + fqdn} target="_blank" rel="noopener noreferrer">{ fqdn }</a></li>)}
</ul>
: '' }
</td>
<td>
{ app.git ? app.git.repo + ' / ' + app.git.branch : '' }
{ app.config?.git ? app.config.git.repo + ' / ' + app.config.git.branch : '' }
</td>
</tr>
)))
......@@ -28,61 +28,46 @@ function AppNginxList (props) {
function loadAppsMock () {
const apps = [
{
name: 'app1',
name: 'nginx1',
org: 'org1',
fqdns: ['fqdn1'],
git: {
repo: 'repo1',
branch: 'branch1'
app: 'app1',
config: {
fqdns: ['fqdn1'],
git: {
repo: 'repo1',
branch: 'branch1'
}
}
},
{
name: 'app2',
name: 'nginx2',
org: 'org1',
fqdns: ['fqdn2'],
git: {
repo: 'repo2',
branch: 'branch1'
}
},
{
name: 'app3',
org: 'org1',
fqdns: ['fqdn3'],
git: {
repo: 'repo3',
branch: 'branch1'
app: 'app2',
config: {
fqdns: ['fqdn2'],
git: {
repo: 'repo2'
}
}
}
]
makeTable(apps)
}
function loadApps () {
const query = JSON.stringify({
query: ` {
nginx(org: "${props.org}") {
name,
org,
fqdns,
git {
repo,
branch
}
},
}`
})
const requestOptions = {
url: window.API_URL + '/graphql',
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: query,
url: window.API_URL + '/api/apps/v1/nginx/?org=' + props.org + '&app=app1',
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('access_token')
},
responseType: 'json'
}
axios
.request(requestOptions)
.then(function (response) {
const res = response.data // Response received from the API
makeTable(res.data.nginx)
makeTable(res.nginx)
return 0
})
.catch(function (err) {
......
......@@ -3,34 +3,48 @@ import { render, screen, waitFor } from '@testing-library/react'
import AppNginxList from './appNginxList'
import nock from 'nock'
test('list nginx apps', async () => {
beforeEach(() => {
nock('http://localhost:8080')
.post('/graphql')
.defaultReplyHeaders({
'access-control-allow-origin': '*',
'access-control-allow-credentials': 'true',
'access-control-allow-headers': 'Authorization'
})
.persist()
.intercept('/api/apps/v1/nginx/', 'OPTIONS')
.query(true)
.reply(200, null)
.get('/api/apps/v1/nginx/')
.query(true)
.reply(200, {
data: {
nginx: [
{
name: 'example-app1',
org: 'test-org',
git: null,
fqdns: null
},
{
name: 'example-app2',
org: 'test-org',
nginx: [
{
name: 'example-app1',
org: 'test-org',
app: 'app1'
},
{
name: 'example-app2',
org: 'test-org',
app: 'app2',
config: {
fqdns: ['www.test.pl', 'www.example.com'],
git: {
repo: 'https://github.com/test/test.git',
branch: 'devel'
}
}
]
}
}, {
'Access-Control-Allow-Origin': '*',
'Content-type': 'application/json'
}
]
})
.get('/api/domains/v1/domains')
.query(true)
.reply(200, [
'example.com'
])
})
test('list nginx apps', async () => {
window.API_URL = 'http://localhost:8080'
render(<AppNginxList org='test-org'/>)
await waitFor(() => expect(screen.getByText('example-app1')).toBeInTheDocument)
......
......@@ -24,27 +24,16 @@ function RegisterForm () {
alert("Passwords didn't match")
return 1
}
const query = JSON.stringify({
query: `mutation {
userRegister(login: "${input.login}",
mail: "${input.mail}",
sn: "${input.sn}",
gn: "${input.gn}",
password: "${input.password}"
)
{
user {
gn,
sn,
mail,
login
},
error
}
}`
})
// const query = JSON.stringify(`{
const query = {
login: input.login,
mail: input.mail,
sn: input.sn,
gn: input.gn,
password: input.password
}
const requestOptions = {
url: window.API_URL + '/graphql',
url: window.API_URL + '/api/users/v1/users/users/',
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: query,
......
......@@ -12,8 +12,16 @@ function SideMenu (props) {
} else {
return <Dropdown.Item key={org} eventKey={org}>{org}</Dropdown.Item>
}
}
)
})
const app = props.apps.map(app => {
const isActive = app === props.currentApp
if (isActive) {
return <Dropdown.Item key={app} eventKey={app} active>{app}</Dropdown.Item>
} else {
return <Dropdown.Item key={app} eventKey={app}>{app}</Dropdown.Item>
}
})
return (
<React.Fragment>
......@@ -31,6 +39,16 @@ function SideMenu (props) {
</Dropdown.Menu>
</Dropdown>
</Nav.Item>
<Nav.Item>
<Dropdown className="mx-2 my-2" onSelect={props.setApp}>
<Dropdown.Toggle id="dropdown-autoclose-true">
{props.currentApp}
</Dropdown.Toggle>
<Dropdown.Menu>
{app}
</Dropdown.Menu>
</Dropdown>
</Nav.Item>
<hr/>
<Nav.Item>
<Nav.Link as={Link} to="/orgs" eventKey="orgs">Orgs</Nav.Link>
......@@ -58,7 +76,10 @@ function SideMenu (props) {
SideMenu.propTypes = {
orgs: PropTypes.arrayOf(PropTypes.string).isRequired,
currentOrg: PropTypes.string.isRequired,
setOrg: PropTypes.func.isRequired
setOrg: PropTypes.func.isRequired,
apps: PropTypes.arrayOf(PropTypes.string).isRequired,
setApp: PropTypes.func.isRequired,
currentApp: PropTypes.string.isRequired
}
export default SideMenu
......@@ -11,8 +11,10 @@ import TopNav from '../components/top_nav'
import SideMenu from '../components/sidemenu'
const ConsolePage = () => {
const [user, setUser] = useState({ login: 'initial', groups: [] })
const [user, setUser] = useState({ username: 'initial', groups: [] })
const [org, setOrg] = useState('ini')
const [app, setApp] = useState('ini')
const [apps, setApps] = useState(['none'])
const navigate = useNavigate()
function getUserinfoMock () {
......@@ -20,30 +22,46 @@ const ConsolePage = () => {
sn: 'test-sn',
gn: 'test-gn',
mail: 'test-mail@mail.ru',
login: 'test-login',
username: 'test-login',
groups: ['test-group1', 'test-group2']
})
}
function getApps (org) {
const requestOptions = {
url: window.API_URL + '/api/apps/v1/app/',
params: {
org
},
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('access_token')
},
responseType: 'json',
withCredentials: true
}
axios
.request(requestOptions)
.then(function (response) {
const res = response.data // Response received from the API
setApps(res)
})
.catch(function (err) {
console.log(err)
setApps(['none'])
// alert("Submit failed")
})
}
function getUserinfo () {
const query = JSON.stringify({
query: `{
user {
user {
sn
gn
mail
login
groups
}
error
}
}`
})
const requestOptions = {
url: window.API_URL + '/graphql',
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: query,
url: window.API_URL + '/api/users/v1/users/userinfo',
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('access_token')
},
responseType: 'json',
withCredentials: true
}
......@@ -51,10 +69,7 @@ const ConsolePage = () => {
.request(requestOptions)
.then(function (response) {
const res = response.data // Response received from the API
if (res.data.user.error) {
setUser(null)
}
setUser(res.data.user.user)
setUser(res)
return 0
})
.catch(function (err) {
......@@ -77,19 +92,27 @@ const ConsolePage = () => {
navigate('register')
return
}
if (user.login === 'initial') {
if (user.username === 'initial') {
return
}
setOrg(user.groups[0])
}, [user])
useEffect(() => {
getApps(org)
}, [org])
useEffect(() => {
setApp(apps[0])
}, [apps])
return (
<React.Fragment>
<TopNav user={user}/>
<Row>
<Col sm={3} lg={2} className='sidemenu'>
{ org !== 'ini'
? <SideMenu currentOrg={org} orgs={user.groups} setOrg={setOrg}/>
? <SideMenu currentOrg={org} orgs={user.groups} setOrg={setOrg} currentApp={app} setApp={setApp} apps={apps}/>
: null
}
</Col>
......
import React from 'react'
import { render, screen, waitFor, fireEvent } from '@testing-library/react'
import ConsolePage from './ConsolePage'
import { Cookies } from 'react-cookie'
import { MemoryRouter, Router } from 'react-router-dom'
import nock from 'nock'
import { createMemoryHistory } from 'history'
import axios from 'axios'
import httpAdapter from 'axios/lib/adapters/http'
beforeEach(() => {
nock.cleanAll()
nock('http://localhost:8080')
.defaultReplyHeaders({
'access-control-allow-origin': '*',
'access-control-allow-credentials': 'true',
'access-control-allow-headers': 'Authorization'
})
.persist()
.intercept('/api/users/v1/users/userinfo', 'OPTIONS')
.reply(200, null)
.get('/api/users/v1/users/userinfo')
.reply(200, {
sn: 'John',
gn: 'test',
mail: 'test-pr@mail.ru',
username: 'test-pr',
groups: [
'test-pr'
]
})
.intercept('/api/apps/v1/app/', 'OPTIONS')
.reply(200, null)
.get('/api/apps/v1/app/')
.query(true)
.reply(200, [
'app1',
'app2'
])
})
test('show login/register page if not logged', async () => {
window.API_URL = 'http://localhost:8080'
nock.cleanAll()
nock('http://localhost:8080')
.post('/graphql')
.reply(200, {
data: {
user: {
error: 'Unauthorized'
}
}
}, {
'Access-Control-Allow-Origin': '*',
.defaultReplyHeaders({
'access-control-allow-origin': '*',
'access-control-allow-credentials': 'true',
'Content-type': 'application/json'
'access-control-allow-headers': 'Authorization'
})
.persist()
.intercept('/api/users/v1/users/userinfo', 'OPTIONS')
.query(true)
.reply(200, null)
.get('/api/users/v1/users/userinfo')
.reply(401)
render(
<MemoryRouter path="/console">
<ConsolePage/>
......@@ -34,8 +65,6 @@ test('show login/register page if not logged', async () => {
})
test('show console page when logged in', () => {
const cookies = new Cookies()
cookies.set('accessToken', 'sometoken')
render(
<MemoryRouter path="/">
<ConsolePage/>
......@@ -47,30 +76,6 @@ test('show console page when logged in', () => {
test('show userinfo in console page', async () => {
window.API_URL = 'http://localhost:8080'
nock('http://localhost:8080')
.post('/graphql')
.twice()
.reply(200, {
data: {
user: {
user: {
sn: 'John',
gn: 'test',
mail: 'test-pr@mail.ru',
login: 'test-pr',
groups: [
'test-pr'
]
}
}
}
}, {
'Access-Control-Allow-Origin': '*',
'access-control-allow-credentials': 'true',
'Content-type': 'application/json'
})
const cookies = new Cookies()
cookies.set('accessToken', 'sometoken')
render(
<MemoryRouter path="/console">
<ConsolePage/>
......@@ -84,30 +89,6 @@ test('show userinfo in console page', async () => {
test('show nginx app in console page', async () => {
window.API_URL = 'http://localhost:8080'
nock('http://localhost:8080')
.post('/graphql')
.twice()
.reply(200, {
data: {
user: {
user: {
sn: 'pr',
gn: 'test',
mail: 'test-pr@mail.ru',
login: 'test-pr',
groups: [
'test-pr'
]
}
}
}
}, {
'Access-Control-Allow-Origin': '*',
'access-control-allow-headers': 'Authorization',
'Content-type': 'application/json'
})
const cookies = new Cookies()
cookies.set('accessToken', 'sometoken')
const history = createMemoryHistory()
history.push('/apps/nginx')
axios.defaults.adapter = httpAdapter
......@@ -122,30 +103,6 @@ test('show nginx app in console page', async () => {
test('show domains in console page', async () => {
window.API_URL = 'http://localhost:8080'
nock('http://localhost:8080')
.post('/graphql')
.twice()
.reply(200, {
data: {
user: {
user: {
sn: 'pr',
gn: 'test',
mail: 'test-pr@mail.ru',
login: 'test-pr',
groups: [
'test-pr'
]
}
}
}
}, {
'Access-Control-Allow-Origin': '*',
'access-control-allow-headers': 'Authorization',
'Content-type': 'application/json'
})
const cookies = new Cookies()
cookies.set('accessToken', 'sometoken')
const history = createMemoryHistory()
history.push('/apps/domain')
axios.defaults.adapter = httpAdapter
......
import React, { useEffect } from 'react'
import { useCookies } from 'react-cookie'
export function LoginPageRedirect () {
const state = Math.random().toString(32).substr(2)
......@@ -17,12 +16,6 @@ export function LoginPageRedirect () {
export function LoginPageCallback () {
const params = new URLSearchParams(window.location.search)
const [cookies, setCookie] = useCookies()
// if(cookies.get("state") != params.get('state')) {
// return (
// <h1> Wrong state </h1>
// )
// }
const requestOptions = {
method: 'POST',
headers: {
......@@ -37,15 +30,8 @@ export function LoginPageCallback () {
fetch(localStorage.getItem('AUTH_URL') + '/token', requestOptions)
.then(response => response.json())
.then(function (data) {
setCookie('accessToken', data.access_token, {
path: '/',
secure: true
})
setCookie('refresh_token', data.refresh_token, {
path: '/',
secure: true
})
console.log(cookies)
localStorage.setItem('access_token', data.access_token)
localStorage.setItem('refresh_token', data.refresh_token)
localStorage.removeItem('oauth2_state')
localStorage.removeItem('AUTH_URL')
localStorage.removeItem('AUTH_CLIENT_ID')
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment