mirror of
https://github.com/penpot/penpot.git
synced 2026-06-26 09:12:06 +00:00
:constructor: Add more fixes
This commit is contained in:
parent
45a0937266
commit
03df00fa72
@ -535,6 +535,46 @@ export function createClient(baseUrl) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Invite members to a team by email.
|
||||
*
|
||||
* @param {string} teamId - Team UUID
|
||||
* @param {string[]} emails - Array of email addresses
|
||||
* @param {string} role - Role for the invited members (e.g. "editor")
|
||||
* @returns {object} Parsed response { status, body }
|
||||
*/
|
||||
function inviteTeamMembers(teamId, emails, role) {
|
||||
const res = rpc("POST", "create-team-invitations", {
|
||||
"team-id": teamId,
|
||||
emails: emails,
|
||||
role: role,
|
||||
});
|
||||
return {
|
||||
status: res.status,
|
||||
body: res.status === 200 ? res.json() : null,
|
||||
raw: res,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an invitation token for a specific email.
|
||||
*
|
||||
* @param {string} teamId - Team UUID
|
||||
* @param {string} email - Invited email address
|
||||
* @returns {object} Parsed response { status, body }
|
||||
*/
|
||||
function getTeamInvitationToken(teamId, email) {
|
||||
const res = rpc("GET", "get-team-invitation-token", {
|
||||
"team-id": teamId,
|
||||
email: email,
|
||||
});
|
||||
return {
|
||||
status: res.status,
|
||||
body: res.status === 200 ? res.json() : null,
|
||||
raw: res,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout the current user.
|
||||
*
|
||||
@ -574,6 +614,8 @@ export function createClient(baseUrl) {
|
||||
deleteFile,
|
||||
deleteProject,
|
||||
deleteTeam,
|
||||
inviteTeamMembers,
|
||||
getTeamInvitationToken,
|
||||
logout,
|
||||
};
|
||||
}
|
||||
|
||||
@ -151,11 +151,39 @@ export function setup() {
|
||||
}
|
||||
console.log(` Created ${users.length} demo profiles`);
|
||||
|
||||
// Login with first user to create project and files
|
||||
// Login with first user to create shared team and files
|
||||
const loginRes = client.login(users[0].email, users[0].password);
|
||||
if (loginRes.status !== 200) fail("Login failed for setup");
|
||||
const teamId = client.getTeams().body[0].id;
|
||||
const projectId = client.createProject(teamId, "Concurrent Edit Project").body.id;
|
||||
|
||||
// Create a shared team so all VUs can access the same file.
|
||||
// Each demo profile gets its own default team; without a shared
|
||||
// team, VUs 2+ would get 404 on get-file.
|
||||
const teamRes = client.createTeam("Concurrent Edit Team");
|
||||
if (teamRes.status !== 200) fail("Failed to create shared team");
|
||||
const sharedTeamId = teamRes.body.id;
|
||||
console.log(` Shared team: ${sharedTeamId}`);
|
||||
|
||||
// Invite remaining users to the shared team and get acceptance tokens.
|
||||
// The tokens are used by each VU via verify-token to join the team.
|
||||
const invitationTokens = [];
|
||||
for (let i = 1; i < TOTAL_VUS; i++) {
|
||||
const invRes = client.inviteTeamMembers(sharedTeamId, [users[i].email], "editor");
|
||||
if (invRes.status !== 200) {
|
||||
console.error(` Invite user ${i}: status=${invRes.status}`);
|
||||
}
|
||||
const tokenRes = client.getTeamInvitationToken(sharedTeamId, users[i].email);
|
||||
if (tokenRes.status === 200 && tokenRes.body) {
|
||||
invitationTokens.push({ vuIndex: i, token: tokenRes.body });
|
||||
}
|
||||
}
|
||||
if (invitationTokens.length > 0) {
|
||||
console.log(` Got ${invitationTokens.length} invitation tokens`);
|
||||
} else {
|
||||
console.log(` All users auto-added (no tokens needed)`);
|
||||
}
|
||||
|
||||
// Create project and files in the shared team
|
||||
const projectId = client.createProject(sharedTeamId, "Concurrent Edit Project").body.id;
|
||||
console.log(` Project: ${projectId}`);
|
||||
|
||||
// Build file/page assignments based on mode
|
||||
@ -180,13 +208,14 @@ export function setup() {
|
||||
const pageIds = [defaultPageId];
|
||||
|
||||
// Add remaining pages
|
||||
// vern never changes on regular edits (only on snapshot restore),
|
||||
// and each add-page increments revn by 1, so no need to re-fetch.
|
||||
for (let i = 1; i < TOTAL_VUS; i++) {
|
||||
const pageId = uuidv4();
|
||||
const pageName = `Page ${i + 1}`;
|
||||
const addRes = addPage(client, fileId, revn, vern, pageId, pageName);
|
||||
if (addRes.status !== 200) fail(`Failed to add page ${i + 1}`);
|
||||
revn = addRes.body.revn;
|
||||
vern = addRes.body.vern;
|
||||
revn++;
|
||||
pageIds.push(pageId);
|
||||
}
|
||||
console.log(` Added ${pageIds.length} pages to file`);
|
||||
@ -222,8 +251,7 @@ export function setup() {
|
||||
const pageName = `Page ${p + 1}`;
|
||||
const addRes = addPage(client, fileId, revn, vern, pageId, pageName);
|
||||
if (addRes.status !== 200) fail(`Failed to add page ${p + 1} to file ${f + 1}`);
|
||||
revn = addRes.body.revn;
|
||||
vern = addRes.body.vern;
|
||||
revn++;
|
||||
pageIds.push(pageId);
|
||||
}
|
||||
console.log(` Added ${pageIds.length} pages to file ${f + 1}`);
|
||||
@ -246,6 +274,7 @@ export function setup() {
|
||||
editMode: EDIT_MODE,
|
||||
users,
|
||||
vuAssignments,
|
||||
invitationTokens,
|
||||
};
|
||||
}
|
||||
|
||||
@ -253,10 +282,17 @@ export function setup() {
|
||||
// Main VU Function — each VU edits its assigned page
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Track which VUs have accepted their invitation (once per VU, not per iteration)
|
||||
const verifiedVus = {};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Main VU Function — each VU edits its assigned page
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export default function (data) {
|
||||
const client = createClient(data.baseUrl);
|
||||
|
||||
// Pick user and assignment from pool
|
||||
// Each VU uses its own demo profile (different users editing the same file)
|
||||
const vuIndex = __VU - 1;
|
||||
const user = data.users[vuIndex];
|
||||
const assignment = data.vuAssignments[vuIndex];
|
||||
@ -268,6 +304,18 @@ export default function (data) {
|
||||
|
||||
// Login
|
||||
if (!assertOk(client.login(user.email, user.password), "login")) fail("login failed");
|
||||
|
||||
// Accept team invitation once per VU (not per iteration).
|
||||
// In devenv the user may already be auto-added; 400 on already-accepted
|
||||
// tokens is harmless — skip the token on subsequent iterations.
|
||||
if (!verifiedVus[__VU]) {
|
||||
const tokenEntry = data.invitationTokens.find((t) => t.vuIndex === vuIndex);
|
||||
if (tokenEntry && tokenEntry.token) {
|
||||
client.rpc("POST", "verify-token", tokenEntry.token);
|
||||
}
|
||||
verifiedVus[__VU] = true;
|
||||
}
|
||||
|
||||
sleep(0.5);
|
||||
|
||||
// Edit loop
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user