Fe2 server management bugfixes (#1787)
* fix(server): inviteList pagination * Fixes from call with fabians * more BE bufxies * reducing server invite precision * Infinite Scroll fixes. Slight design change to "update available" * fixed tests --------- Co-authored-by: Kristaps Fabians Geikins <fabis94@live.com>
This commit is contained in:
committed by
GitHub
parent
d95d03605e
commit
44bfa6d2c8
@@ -12,6 +12,10 @@ import { expect } from 'chai'
|
||||
import { ApolloServer } from 'apollo-server-express'
|
||||
import { ServerInviteRecord } from '@/modules/serverinvites/helpers/types'
|
||||
import { Optional } from '@/modules/shared/helpers/typeHelper'
|
||||
import { wait } from '@speckle/shared'
|
||||
|
||||
// To ensure that the invites are created in the correct order, we need to wait a bit between each creation
|
||||
const WAIT_TIMEOUT = 5
|
||||
|
||||
function randomEl<T>(array: T[]): T {
|
||||
return array[Math.floor(Math.random() * array.length)]
|
||||
@@ -90,18 +94,18 @@ describe('[Admin users list]', () => {
|
||||
let remainingSearchQueryInviteCount = SEARCH_QUERY_RESULT_COUNT
|
||||
|
||||
// Create Users
|
||||
await Promise.all(
|
||||
// count - 1, cause `me` also exists
|
||||
times(USER_COUNT - 1, (i) =>
|
||||
createUser({
|
||||
name: `User #${i} - ${
|
||||
remainingSearchQueryUserCount-- >= 1 ? SEARCH_QUERY : ''
|
||||
}`,
|
||||
email: `speckleuser${i}@gmail.com`,
|
||||
password: 'sn3aky-1337-b1m'
|
||||
}).then((id) => userIds.push(id))
|
||||
)
|
||||
)
|
||||
// count - 1, cause `me` also exists
|
||||
for (let i = 0; i < USER_COUNT - 1; i++) {
|
||||
const id = await createUser({
|
||||
name: `User #${i} - ${
|
||||
remainingSearchQueryUserCount-- >= 1 ? SEARCH_QUERY : ''
|
||||
}`,
|
||||
email: `speckleuser${i}@gmail.com`,
|
||||
password: 'sn3aky-1337-b1m'
|
||||
})
|
||||
userIds.push(id)
|
||||
await wait(WAIT_TIMEOUT)
|
||||
}
|
||||
|
||||
// Create streams
|
||||
const streamData: { id: string; ownerId: string }[] = []
|
||||
@@ -117,34 +121,35 @@ describe('[Admin users list]', () => {
|
||||
)
|
||||
|
||||
// Create invites
|
||||
await Promise.all([
|
||||
// Server invites
|
||||
...times(SERVER_INVITE_COUNT, (i) =>
|
||||
createInviteDirectly(
|
||||
{
|
||||
email: `randominvitee${i}.${
|
||||
remainingSearchQueryInviteCount-- >= 1 ? SEARCH_QUERY : ''
|
||||
}@gmail.com`
|
||||
},
|
||||
randomEl(userIds)
|
||||
)
|
||||
),
|
||||
// Stream invites
|
||||
...times(STREAM_INVITE_COUNT, (i) => {
|
||||
const { id: streamId, ownerId } = randomEl(streamData)
|
||||
const email = `streamrandominvitee${i}.${
|
||||
remainingSearchQueryInviteCount-- >= 1 ? SEARCH_QUERY : ''
|
||||
}@gmail.com`
|
||||
// Server invites
|
||||
for (let i = 0; i < SERVER_INVITE_COUNT; i++) {
|
||||
await createInviteDirectly(
|
||||
{
|
||||
email: `randominvitee${i}.${
|
||||
remainingSearchQueryInviteCount-- >= 1 ? SEARCH_QUERY : ''
|
||||
}@gmail.com`
|
||||
},
|
||||
randomEl(userIds)
|
||||
)
|
||||
await wait(WAIT_TIMEOUT)
|
||||
}
|
||||
|
||||
return createInviteDirectly(
|
||||
{
|
||||
streamId,
|
||||
email
|
||||
},
|
||||
ownerId
|
||||
)
|
||||
})
|
||||
])
|
||||
// Stream invites
|
||||
for (let i = 0; i < STREAM_INVITE_COUNT; i++) {
|
||||
const { id: streamId, ownerId } = randomEl(streamData)
|
||||
const email = `streamrandominvitee${i}.${
|
||||
remainingSearchQueryInviteCount-- >= 1 ? SEARCH_QUERY : ''
|
||||
}@gmail.com`
|
||||
|
||||
await createInviteDirectly(
|
||||
{
|
||||
streamId,
|
||||
email
|
||||
},
|
||||
ownerId
|
||||
)
|
||||
await wait(WAIT_TIMEOUT)
|
||||
}
|
||||
|
||||
// Create a few more stream invites to registered users, which should not appear in
|
||||
// the users list
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import { Knex } from 'knex'
|
||||
|
||||
/**
|
||||
* MIGRATING STREAMS TIMESTAMP FIELDS TO A LOWER PRECISION, CAUSE JS CANT HANDLE
|
||||
* IT BEING THAT HIGH AND THIS GENERATES BUGS
|
||||
*/
|
||||
|
||||
const TABLE_NAME = 'server_invites'
|
||||
const TIMESTAMP_COLUMNS = ['createdAt']
|
||||
|
||||
export async function up(knex: Knex): Promise<void> {
|
||||
await knex.schema.alterTable(TABLE_NAME, (table) => {
|
||||
TIMESTAMP_COLUMNS.forEach((col) => {
|
||||
table
|
||||
.timestamp(col, { precision: 3, useTz: true })
|
||||
.defaultTo(knex.fn.now())
|
||||
.alter()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export async function down(knex: Knex): Promise<void> {
|
||||
await knex.schema.alterTable(TABLE_NAME, (table) => {
|
||||
TIMESTAMP_COLUMNS.forEach((col) => {
|
||||
table
|
||||
.timestamp(col, { precision: 6, useTz: true })
|
||||
.defaultTo(knex.fn.now())
|
||||
.alter()
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -13,7 +13,7 @@ const { getStream } = require('@/modules/core/repositories/streams')
|
||||
/**
|
||||
* Use this wherever you're retrieving invites, not necessarily where you're writing to them
|
||||
*/
|
||||
const getInvitesBaseQuery = () => {
|
||||
const getInvitesBaseQuery = (sort = 'asc') => {
|
||||
const q = ServerInvites.knex().select(ServerInvites.cols)
|
||||
|
||||
// join just to ensure we don't retrieve invalid invites
|
||||
@@ -25,7 +25,7 @@ const getInvitesBaseQuery = () => {
|
||||
w1.whereNull(ServerInvites.col.resourceId).orWhereNotNull(Streams.col.id)
|
||||
})
|
||||
|
||||
q.orderBy(ServerInvites.col.createdAt)
|
||||
q.orderBy(ServerInvites.col.createdAt, sort)
|
||||
|
||||
return q
|
||||
}
|
||||
@@ -225,8 +225,8 @@ async function deleteStreamInvite(inviteId) {
|
||||
.delete()
|
||||
}
|
||||
|
||||
function findServerInvitesBaseQuery(searchQuery) {
|
||||
const q = getInvitesBaseQuery()
|
||||
function findServerInvitesBaseQuery(searchQuery, sort) {
|
||||
const q = getInvitesBaseQuery(sort)
|
||||
|
||||
if (searchQuery) {
|
||||
// TODO: Is this safe from SQL injection?
|
||||
@@ -272,10 +272,9 @@ async function findServerInvites(searchQuery, limit, offset) {
|
||||
* @returns {Promise<ServerInviteRecord[]>}
|
||||
*/
|
||||
async function queryServerInvites(searchQuery, limit, cursor) {
|
||||
const q = findServerInvitesBaseQuery(searchQuery)
|
||||
.limit(limit)
|
||||
.orderBy(ServerInvites.col.createdAt, 'desc')
|
||||
if (cursor) q.where(ServerInvites.col.createdAt, '<', cursor)
|
||||
const q = findServerInvitesBaseQuery(searchQuery, 'desc').limit(limit)
|
||||
|
||||
if (cursor) q.where(ServerInvites.col.createdAt, '<', cursor.toISOString())
|
||||
return await q
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user