Skip to content

Commit

Permalink
UBERF-5575: Fix workspace join (hcengineering#4684)
Browse files Browse the repository at this point in the history
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
Signed-off-by: Tiago Cruz <tcruz@netic.io>
  • Loading branch information
haiodo authored and tjaoc committed Mar 5, 2024
1 parent 5f7a544 commit 14bcf20
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 9 deletions.
19 changes: 13 additions & 6 deletions server/account/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,10 +373,10 @@ export async function join (
const invite = await getInvite(db, inviteId)
const workspace = await checkInvite(invite, email)
console.log(`join attempt:${email}, ${workspace.name}`)
await assignWorkspace(db, productId, email, workspace.name)
const ws = await assignWorkspace(db, productId, email, workspace.name)

const token = (await login(db, productId, email, password)).token
const result = await selectWorkspace(db, productId, token, workspace.name)
const result = await selectWorkspace(db, productId, token, ws.workspaceUrl ?? ws.workspace)
await useInvite(db, inviteId)
return result
}
Expand Down Expand Up @@ -490,10 +490,10 @@ export async function signUpJoin (
last,
invite?.emailMask === email || sesURL === undefined || sesURL === ''
)
await assignWorkspace(db, productId, email, workspace.name)
const ws = await assignWorkspace(db, productId, email, workspace.name)

const token = (await login(db, productId, email, password)).token
const result = await selectWorkspace(db, productId, token, workspace.name)
const result = await selectWorkspace(db, productId, token, ws.workspaceUrl ?? ws.workspace)
await useInvite(db, inviteId)
return result
}
Expand Down Expand Up @@ -997,7 +997,7 @@ export async function assignWorkspace (
workspaceId: string,
shouldReplaceAccount: boolean = false,
client?: Client
): Promise<void> {
): Promise<Workspace> {
const email = cleanEmail(_email)
const initWS = getMetadata(toolPlugin.metadata.InitWorkspace)
if (initWS !== undefined && initWS === workspaceId) {
Expand All @@ -1018,6 +1018,7 @@ export async function assignWorkspace (
await db
.collection(ACCOUNT_COLLECTION)
.updateOne({ _id: workspaceInfo.account._id }, { $addToSet: { workspaces: workspaceInfo.workspace._id } })
return workspaceInfo.workspace
}

async function createEmployee (ops: TxOperations, name: string, _email: string): Promise<Ref<Person>> {
Expand Down Expand Up @@ -1276,7 +1277,13 @@ export async function checkJoin (
const { email } = decodeToken(token)
const invite = await getInvite(db, inviteId)
const workspace = await checkInvite(invite, email)
return await selectWorkspace(db, productId, token, workspace.name, false)
const ws = await getWorkspaceById(db, productId, workspace.name)
if (ws === null) {
throw new PlatformError(
new Status(Severity.ERROR, platform.status.WorkspaceNotFound, { workspace: workspace.name })
)
}
return await selectWorkspace(db, productId, token, ws?.workspaceUrl ?? ws.workspace, false)
}

/**
Expand Down
25 changes: 25 additions & 0 deletions tests/sanity/tests/model/signin-page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { expect, type Locator, type Page } from '@playwright/test'
import { CommonPage } from './common-page'
import { SignUpData } from './common-types'

export class SignInJoinPage extends CommonPage {
readonly page: Page
readonly inputEmail: Locator
readonly inputPassword: Locator
readonly buttonJoin: Locator

constructor (page: Page) {
super()
this.page = page
this.inputEmail = page.locator('input[name="email"]')
this.inputPassword = page.locator('//div[text()="Password"]/../input')
this.buttonJoin = page.locator('button', { hasText: 'Join' })
}

async join (data: Pick<SignUpData, 'email' | 'password'>): Promise<void> {
await this.inputEmail.fill(data.email)
await this.inputPassword.fill(data.password)
expect(await this.buttonJoin.isEnabled()).toBe(true)
await this.buttonJoin.click()
}
}
15 changes: 12 additions & 3 deletions tests/sanity/tests/model/signup-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export class SignUpPage extends CommonPage {
readonly inputNewPassword: Locator
readonly inputRepeatPassword: Locator
readonly buttonSignUp: Locator
readonly buttonJoin: Locator

constructor (page: Page) {
super()
Expand All @@ -20,15 +21,23 @@ export class SignUpPage extends CommonPage {
this.inputNewPassword = page.locator('//div[text()="Password"]/../input')
this.inputRepeatPassword = page.locator('//div[text()="Repeat password"]/../input')
this.buttonSignUp = page.locator('button', { hasText: 'Sign Up' })
this.buttonJoin = page.locator('button', { hasText: 'Join' })
}

async signUp (data: SignUpData): Promise<void> {
async signUp (data: SignUpData, mode: 'join' | 'signup' = 'signup'): Promise<void> {
await this.inputFirstName.fill(data.firstName)
await this.inputLastName.fill(data.lastName)
await this.inputEmail.fill(data.email)
await this.inputNewPassword.fill(data.password)
await this.inputRepeatPassword.fill(data.password)
expect(await this.buttonSignUp.isEnabled()).toBe(true)
await this.buttonSignUp.click()
switch (mode) {
case 'join':
expect(await this.buttonJoin.isEnabled()).toBe(true)
await this.buttonJoin.click()
break
case 'signup':
expect(await this.buttonSignUp.isEnabled()).toBe(true)
await this.buttonSignUp.click()
}
}
}
109 changes: 109 additions & 0 deletions tests/sanity/tests/workspace/create.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { NewIssue } from '../model/tracker/types'
import { IssuesPage } from '../model/tracker/issues-page'
import { IssuesDetailsPage } from '../model/tracker/issues-details-page'
import { TrackerNavigationMenuPage } from '../model/tracker/tracker-navigation-menu-page'
import { SignInJoinPage } from '../model/signin-page'

test.describe('Workspace tests', () => {
test('Create a workspace with a custom name', async ({ page }) => {
Expand Down Expand Up @@ -122,4 +123,112 @@ test.describe('Workspace tests', () => {
await selectWorkspacePage.buttonWorkspaceName.fill(newWorkspaceName)
await selectWorkspacePage.checkInfoSectionNotExist(page)
})

test('Create a workspace with join link', async ({ page, browser }) => {
const newUser: SignUpData = {
firstName: `FirstName-${generateId()}`,
lastName: `LastName-${generateId()}`,
email: `email+${generateId()}@gmail.com`,
password: '1234'
}
const newWorkspaceName = `Some HULY #@$ WS - ${generateId(12)}`

const loginPage = new LoginPage(page)
await loginPage.goto()
await loginPage.linkSignUp.click()

const signUpPage = new SignUpPage(page)
await signUpPage.signUp(newUser)

const selectWorkspacePage = new SelectWorkspacePage(page)
await selectWorkspacePage.buttonCreateWorkspace.click()
await selectWorkspacePage.createWorkspace(newWorkspaceName)

const leftSideMenuPage = new LeftSideMenuPage(page)
await leftSideMenuPage.buttonTracker.click()

// Generate invite link

await page.click('#profile-button')
await page.click('button:has-text("Invite to workspace")')
await page.click('button:has-text("Get invite link")')

const linkText = await page.locator('.antiPopup .link').textContent()

const page2 = await browser.newPage()

await page2.goto(linkText ?? '')

const newUser2: SignUpData = {
firstName: `FirstName2-${generateId()}`,
lastName: `LastName2-${generateId()}`,
email: `email+${generateId()}@gmail.com`,
password: '1234'
}

await page2.getByRole('link', { name: 'Sign Up' }).click()
const signUpPage2 = new SignUpPage(page2)
await signUpPage2.signUp(newUser2, 'join')

const leftSideMenuPage2 = new LeftSideMenuPage(page2)
await leftSideMenuPage2.buttonTracker.click()
})

test('Create a workspace with join link - existing account', async ({ page, browser }) => {
const newUser: SignUpData = {
firstName: `FirstName-${generateId()}`,
lastName: `LastName-${generateId()}`,
email: `email+${generateId()}@gmail.com`,
password: '1234'
}
const newWorkspaceName = `Some HULY #@$ WS - ${generateId(12)}`

const loginPage = new LoginPage(page)
await loginPage.goto()
await loginPage.linkSignUp.click()

const signUpPage = new SignUpPage(page)
await signUpPage.signUp(newUser)

const selectWorkspacePage = new SelectWorkspacePage(page)
await selectWorkspacePage.buttonCreateWorkspace.click()
await selectWorkspacePage.createWorkspace(newWorkspaceName)

const leftSideMenuPage = new LeftSideMenuPage(page)
await leftSideMenuPage.buttonTracker.click()

// Generate invite link

await page.click('#profile-button')
await page.click('button:has-text("Invite to workspace")')
await page.click('button:has-text("Get invite link")')

const linkText = await page.locator('.antiPopup .link').textContent()

const page2 = await browser.newPage()

const loginPage2 = new LoginPage(page2)
await loginPage2.goto()
await loginPage2.linkSignUp.click()

const newUser2: SignUpData = {
firstName: `FirstName2-${generateId()}`,
lastName: `LastName2-${generateId()}`,
email: `email+${generateId()}@gmail.com`,
password: '1234'
}

const signUpPage2 = new SignUpPage(page2)
await signUpPage2.signUp(newUser2)

// Ok we signed in, and no workspace present.

await page2.goto(linkText ?? '')

const joinPage = new SignInJoinPage(page2)
await joinPage.join(newUser2)

const leftSideMenuPage2 = new LeftSideMenuPage(page2)
await leftSideMenuPage2.buttonTracker.click()
})
})

0 comments on commit 14bcf20

Please sign in to comment.