This commit is contained in:
mike12345567 2023-01-06 16:46:50 +00:00
parent 1e046b9d7f
commit 60371d828e
9 changed files with 902 additions and 822 deletions

View File

@ -45,7 +45,7 @@
"dev:server": "yarn run kill-server && lerna run --parallel dev:builder --concurrency 1 --scope @budibase/backend-core --scope @budibase/worker --scope @budibase/server",
"test": "lerna run test && yarn test:pro",
"test:pro": "bash scripts/pro/test.sh",
"lint:eslint": "eslint packages",
"lint:eslint": "eslint packages && eslint qa-core",
"lint:prettier": "prettier --check \"packages/**/*.{js,ts,svelte}\"",
"lint": "yarn run lint:eslint && yarn run lint:prettier",
"lint:fix:eslint": "eslint --fix packages qa-core",
@ -84,4 +84,4 @@
"install:pro": "bash scripts/pro/install.sh",
"dep:clean": "yarn clean && yarn bootstrap"
}
}
}

View File

@ -4,130 +4,128 @@ import InternalAPIClient from "./InternalAPIClient"
import { responseMessage } from "../fixtures/types/responseMessage"
export default class UserManagementApi {
api: InternalAPIClient
api: InternalAPIClient
constructor(apiClient: InternalAPIClient) {
this.api = apiClient
}
constructor(apiClient: InternalAPIClient) {
this.api = apiClient
}
async search(): Promise<[Response, Partial<User>[]]> {
const response = await this.api.post(`/global/users/search`, {})
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json.data.length).toBeGreaterThan(0)
return [response, json]
}
async search(): Promise<[Response, Partial<User>[]]> {
const response = await this.api.post(`/global/users/search`, {})
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json.data.length).toBeGreaterThan(0)
return [response, json]
}
async getSelf(): Promise<[Response, Partial<User>]> {
const response = await this.api.get(`/global/self`)
const json = await response.json()
expect(response).toHaveStatusCode(200)
return [response, json]
}
async getSelf(): Promise<[Response, Partial<User>]> {
const response = await this.api.get(`/global/self`)
const json = await response.json()
expect(response).toHaveStatusCode(200)
return [response, json]
}
async getAll(): Promise<[Response, Partial<User>[]]> {
const response = await this.api.get(`/global/users`)
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json.length).toBeGreaterThan(0)
return [response, json]
}
async getAll(): Promise<[Response, Partial<User>[]]> {
const response = await this.api.get(`/global/users`)
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json.length).toBeGreaterThan(0)
return [response, json]
}
// This endpoint is used for one or more users when we want add users with passwords set.
async addMultiple(userList: Partial<User>[]): Promise<[Response, any]> {
const body = {
create: {
users: userList,
groups: []
}
}
const response = await this.api.post(`/global/users/bulk`, { body })
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json.created.unsuccessful.length).toEqual(0)
expect(json.created.successful.length).toEqual(body.create.users.length)
return [response, json]
// This endpoint is used for one or more users when we want add users with passwords set.
async addMultiple(userList: Partial<User>[]): Promise<[Response, any]> {
const body = {
create: {
users: userList,
groups: [],
},
}
const response = await this.api.post(`/global/users/bulk`, { body })
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json.created.unsuccessful.length).toEqual(0)
expect(json.created.successful.length).toEqual(body.create.users.length)
return [response, json]
}
async deleteMultiple(userId: string[]): Promise<[Response, responseMessage]> {
const body = {
delete: {
userIds: [
userId
]
}
}
const response = await this.api.post(`/global/users/bulk`, { body })
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json.deleted.successful.length).toEqual(1)
expect(json.deleted.unsuccessful.length).toEqual(0)
expect(json.deleted.successful[0].userId).toEqual(userId)
return [response, json]
}
async delete(userId: string): Promise<[Response, UserDeletedEvent]> {
const response = await this.api.del(`/global/users/${userId}`)
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json.message).toEqual(`User ${userId} deleted.`)
return [response, json]
async deleteMultiple(userId: string[]): Promise<[Response, responseMessage]> {
const body = {
delete: {
userIds: [userId],
},
}
const response = await this.api.post(`/global/users/bulk`, { body })
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json.deleted.successful.length).toEqual(1)
expect(json.deleted.unsuccessful.length).toEqual(0)
expect(json.deleted.successful[0].userId).toEqual(userId)
return [response, json]
}
async delete(userId: string): Promise<[Response, UserDeletedEvent]> {
const response = await this.api.del(`/global/users/${userId}`)
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json.message).toEqual(`User ${userId} deleted.`)
return [response, json]
}
async invite(body: any): Promise<[Response, responseMessage]> {
const response = await this.api.post(`/global/users/multi/invite`, { body })
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json.unsuccessful.length).toEqual(0)
expect(json.successful.length).toEqual(body.length)
async invite(body: any): Promise<[Response, responseMessage]> {
const response = await this.api.post(`/global/users/multi/invite`, { body })
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json.unsuccessful.length).toEqual(0)
expect(json.successful.length).toEqual(body.length)
return [response, json]
}
return [response, json]
}
async getRoles(): Promise<[Response, Role[]]> {
const response = await this.api.get(`/roles`)
const json = await response.json()
expect(response).toHaveStatusCode(200)
return [response, json]
}
async getRoles(): Promise<[Response, Role[]]> {
const response = await this.api.get(`/roles`)
const json = await response.json()
expect(response).toHaveStatusCode(200)
return [response, json]
}
async updateInfo(body: any): Promise<[Response, User]> {
const response = await this.api.post(`/global/users/`, { body })
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json._id).toEqual(body._id)
expect(json._rev).not.toEqual(body._rev)
return [response, json]
}
async updateInfo(body: any): Promise<[Response, User]> {
const response = await this.api.post(`/global/users/`, { body })
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json._id).toEqual(body._id)
expect(json._rev).not.toEqual(body._rev)
return [response, json]
}
async forcePasswordReset(body: any): Promise<[Response, User]> {
const response = await this.api.post(`/global/users/`, { body })
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json._id).toEqual(body._id)
expect(json._rev).not.toEqual(body._rev)
return [response, json]
}
async forcePasswordReset(body: any): Promise<[Response, User]> {
const response = await this.api.post(`/global/users/`, { body })
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json._id).toEqual(body._id)
expect(json._rev).not.toEqual(body._rev)
return [response, json]
}
async getInfo(userId: string): Promise<[Response, User]> {
const response = await this.api.get(`/global/users/${userId}`)
const json = await response.json()
expect(response).toHaveStatusCode(200)
return [response, json]
}
async getInfo(userId: string): Promise<[Response, User]> {
const response = await this.api.get(`/global/users/${userId}`)
const json = await response.json()
expect(response).toHaveStatusCode(200)
return [response, json]
}
async changeSelfPassword(body: Partial<User>): Promise<[Response, User]> {
const response = await this.api.post(`/global/self`, { body })
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json._id).toEqual(body._id)
expect(json._rev).not.toEqual(body._rev)
return [response, json]
}
async changeSelfPassword(body: Partial<User>): Promise<[Response, User]> {
const response = await this.api.post(`/global/self`, { body })
const json = await response.json()
expect(response).toHaveStatusCode(200)
expect(json._id).toEqual(body._id)
expect(json._rev).not.toEqual(body._rev)
return [response, json]
}
async createRole(body: Partial<UserRoles>): Promise<[Response, UserRoles]> {
const response = await this.api.post(`/roles`, { body })
const json = await response.json()
expect(response).toHaveStatusCode(200)
return [response, json]
}
}
async createRole(body: Partial<UserRoles>): Promise<[Response, UserRoles]> {
const response = await this.api.post(`/roles`, { body })
const json = await response.json()
expect(response).toHaveStatusCode(200)
return [response, json]
}
}

View File

@ -13,13 +13,12 @@ export const generateApp = (
// Applications type doesn't work here, save to add useTemplate parameter?
export const appFromTemplate = (): any => {
return ({
return {
name: generator.word(),
url: `/${generator.word()}`,
useTemplate: "true",
templateName: "Near Miss Register",
templateKey: "app/near-miss-register",
templateFile: undefined,
})
}
}

View File

@ -1,80 +1,82 @@
import generator from "../../generator";
import { User } from "@budibase/types";
import generator from "../../generator"
import { User } from "@budibase/types"
const generateDeveloper = (): Partial<User> => {
const randomId = generator.guid();
return ({
email: `pedro+${randomId}@budibase.com`,
password: randomId,
roles: {},
forceResetPassword: true,
builder: {
global: true
}
})
const randomId = generator.guid()
return {
email: `pedro+${randomId}@budibase.com`,
password: randomId,
roles: {},
forceResetPassword: true,
builder: {
global: true,
},
}
}
const generateAdmin = (): Partial<User> => {
const randomId = generator.guid();
return ({
email: `pedro+${randomId}@budibase.com`,
password: randomId,
roles: {},
forceResetPassword: true,
admin: {
global: true
},
builder: {
global: true
}
})
const randomId = generator.guid()
return {
email: `pedro+${randomId}@budibase.com`,
password: randomId,
roles: {},
forceResetPassword: true,
admin: {
global: true,
},
builder: {
global: true,
},
}
}
const generateAppUser = (): Partial<User> => {
const randomId = generator.guid();
return ({
email: `pedro+${randomId}@budibase.com`,
password: randomId,
roles: {},
forceResetPassword: true,
admin: {
global: false
},
builder: {
global: false
}
})
const randomId = generator.guid()
return {
email: `pedro+${randomId}@budibase.com`,
password: randomId,
roles: {},
forceResetPassword: true,
admin: {
global: false,
},
builder: {
global: false,
},
}
}
export const generateInviteUser = (): Object[] => {
const randomId = generator.guid();
return [{
email: `pedro+${randomId}@budibase.com`,
userInfo: {
userGroups: []
}
}]
const randomId = generator.guid()
return [
{
email: `pedro+${randomId}@budibase.com`,
userInfo: {
userGroups: [],
},
},
]
}
export const generateUser = (amount: number = 1, role?: string): Partial<User>[] => {
const userList: Partial<User>[] = [];
for (let i = 0; i < amount; i++) {
switch (role) {
case "admin":
userList.push(generateAdmin());
break;
case "developer":
userList.push(generateDeveloper());
break;
case "appUser":
userList.push(generateAppUser());
break;
default:
userList.push(generateAppUser());
break;
}
export const generateUser = (
amount: number = 1,
role?: string
): Partial<User>[] => {
const userList: Partial<User>[] = []
for (let i = 0; i < amount; i++) {
switch (role) {
case "admin":
userList.push(generateAdmin())
break
case "developer":
userList.push(generateDeveloper())
break
case "appUser":
userList.push(generateAppUser())
break
default:
userList.push(generateAppUser())
break
}
return userList
}
}
return userList
}

View File

@ -2,7 +2,10 @@ import TestConfiguration from "../../../config/internal-api/TestConfiguration"
import { Application } from "@budibase/server/api/controllers/public/mapping/types"
import { db } from "@budibase/backend-core"
import InternalAPIClient from "../../../config/internal-api/TestConfiguration/InternalAPIClient"
import { generateApp, appFromTemplate } from "../../../config/internal-api/fixtures/applications"
import {
generateApp,
appFromTemplate,
} from "../../../config/internal-api/fixtures/applications"
import generator from "../../../config/generator"
import generateScreen from "../../../config/internal-api/fixtures/screens"
@ -18,7 +21,6 @@ describe("Internal API - Application creation, update, publish and delete", () =
await config.afterAll()
})
it("Get applications without applications", async () => {
await config.applications.fetchEmptyAppList()
})

View File

@ -1,7 +1,10 @@
import TestConfiguration from "../../../config/internal-api/TestConfiguration"
import { App } from "@budibase/types"
import InternalAPIClient from "../../../config/internal-api/TestConfiguration/InternalAPIClient"
import { generateApp, appFromTemplate } from "../../../config/internal-api/fixtures/applications"
import {
generateApp,
appFromTemplate,
} from "../../../config/internal-api/fixtures/applications"
import { Screen } from "@budibase/types"
import generateScreen from "../../../config/internal-api/fixtures/screens"

View File

@ -5,86 +5,84 @@ import { generateUser } from "../../../config/internal-api/fixtures/userManageme
import { User } from "@budibase/types"
describe("Internal API - User Management & Permissions", () => {
const api = new InternalAPIClient()
const config = new TestConfiguration<Application>(api)
const api = new InternalAPIClient()
const config = new TestConfiguration<Application>(api)
// Before each test, login as admin. Some tests will require login as a different user
beforeEach(async () => {
await config.loginAsAdmin()
})
// Before each test, login as admin. Some tests will require login as a different user
beforeEach(async () => {
await config.loginAsAdmin()
})
afterAll(async () => {
await config.afterAll()
})
afterAll(async () => {
await config.afterAll()
})
it("Add Users with different roles", async () => {
await config.users.search()
await config.users.getRoles()
it("Add Users with different roles", async () => {
await config.users.search()
await config.users.getRoles()
const admin = generateUser(1, "admin")
expect(admin[0].builder?.global).toEqual(true)
expect(admin[0].admin?.global).toEqual(true)
const developer = generateUser(1, "developer")
expect(developer[0].builder?.global).toEqual(true)
const appUser = generateUser(1, "appUser")
expect(appUser[0].builder?.global).toEqual(false)
expect(appUser[0].admin?.global).toEqual(false)
const admin = generateUser(1, "admin")
expect(admin[0].builder?.global).toEqual(true)
expect(admin[0].admin?.global).toEqual(true)
const developer = generateUser(1, "developer")
expect(developer[0].builder?.global).toEqual(true)
const appUser = generateUser(1, "appUser")
expect(appUser[0].builder?.global).toEqual(false)
expect(appUser[0].admin?.global).toEqual(false)
const userList = [...admin, ...developer, ...appUser]
const userList = [...admin, ...developer, ...appUser]
await config.users.addMultiple(userList)
await config.users.addMultiple(userList)
const [allUsersResponse, allUsersJson] = await config.users.getAll()
expect(allUsersJson.length).toBeGreaterThan(0)
const [allUsersResponse, allUsersJson] = await config.users.getAll()
expect(allUsersJson.length).toBeGreaterThan(0)
})
it("Delete User", async () => {
const appUser = generateUser()
expect(appUser[0].builder?.global).toEqual(false)
expect(appUser[0].admin?.global).toEqual(false)
const [userResponse, userJson] = await config.users.addMultiple(appUser)
const userId = userJson.created.successful[0]._id
await config.users.delete(<string>userId)
})
it("Reset Password", async () => {
const appUser = generateUser()
expect(appUser[0].builder?.global).toEqual(false)
expect(appUser[0].admin?.global).toEqual(false)
const [userResponse, userJson] = await config.users.addMultiple(appUser)
const [userInfoResponse, userInfoJson] = await config.users.getInfo(
userJson.created.successful[0]._id
)
const body: User = {
...userInfoJson,
password: "newPassword",
}
await config.users.forcePasswordReset(body)
})
})
it("Delete User", async () => {
const appUser = generateUser()
expect(appUser[0].builder?.global).toEqual(false)
expect(appUser[0].admin?.global).toEqual(false)
const [userResponse, userJson] = await config.users.addMultiple(appUser)
const userId = userJson.created.successful[0]._id
await config.users.delete(<string>userId)
})
it("Reset Password", async () => {
const appUser = generateUser()
expect(appUser[0].builder?.global).toEqual(false)
expect(appUser[0].admin?.global).toEqual(false)
const [userResponse, userJson] = await config.users.addMultiple(appUser)
const [userInfoResponse, userInfoJson] = await config.users.getInfo(userJson.created.successful[0]._id)
const body: User = {
...userInfoJson,
password: "newPassword"
}
await config.users.forcePasswordReset(body)
})
it("Change User information", async () => {
const appUser = generateUser()
expect(appUser[0].builder?.global).toEqual(false)
expect(appUser[0].admin?.global).toEqual(false)
const [userResponse, userJson] = await config.users.addMultiple(appUser)
const [userInfoResponse, userInfoJson] = await config.users.getInfo(userJson.created.successful[0]._id)
const body: User = {
...userInfoJson,
firstName: "newFirstName",
lastName: "newLastName",
builder: {
global: true
}
}
await config.users.updateInfo(body)
const [changedUserInfoResponse, changedUserInfoJson] = await config.users.getInfo(userJson.created.successful[0]._id)
expect(changedUserInfoJson.builder?.global).toBeDefined()
expect(changedUserInfoJson.builder?.global).toEqual(true)
})
it("Change User information", async () => {
const appUser = generateUser()
expect(appUser[0].builder?.global).toEqual(false)
expect(appUser[0].admin?.global).toEqual(false)
const [userResponse, userJson] = await config.users.addMultiple(appUser)
const [userInfoResponse, userInfoJson] = await config.users.getInfo(
userJson.created.successful[0]._id
)
const body: User = {
...userInfoJson,
firstName: "newFirstName",
lastName: "newLastName",
builder: {
global: true,
},
}
await config.users.updateInfo(body)
const [changedUserInfoResponse, changedUserInfoJson] =
await config.users.getInfo(userJson.created.successful[0]._id)
expect(changedUserInfoJson.builder?.global).toBeDefined()
expect(changedUserInfoJson.builder?.global).toEqual(true)
})
})

View File

@ -73,15 +73,15 @@ describe("Public API - /applications endpoints", () => {
})
it("POST - unpublish an unpublished application", async () => {
const [response] = await config.applications.unpublish(
config.context._id
)
const [response] = await config.applications.unpublish(config.context._id)
expect(response).toHaveStatusCode(400)
})
it("DELETE - delete a published application and the dev application", async () => {
await config.applications.publish(config.context._id)
const [response, deletion] = await config.applications.delete(config.context._id)
const [response, deletion] = await config.applications.delete(
config.context._id
)
expect(response).toHaveStatusCode(200)
expect(deletion._id).toEqual(config.context._id)