Files
supabase/tests/features/javascript/authentication.spec.ts
egor-romanov 1895bf701e chore: upd integration tests (#9320)
* extend integration test suite and move to v2
* update workflow
* change tests to run against cli setup
2022-10-12 14:50:04 +03:00

331 lines
11 KiB
TypeScript

import { suite, test, timeout } from '@testdeck/jest'
import { faker } from '@faker-js/faker'
import { Severity } from 'allure-js-commons'
import { AuthChangeEvent, Session } from '@supabase/supabase-js'
import { FEATURE } from '../templates/enums'
import { description, feature, log, severity, step } from '../../.jest/jest-custom-reporter'
import { Hooks } from './hooks'
@suite('authentication')
class Authentication extends Hooks {
@feature(FEATURE.AUTHENTICATION)
@severity(Severity.BLOCKER)
@description('When user sign up then corresponding user in auth schema should be created')
@test
async 'signup should create user'() {
const supabase = this.createSupaClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY_ANON)
const fakeUser = {
email: faker.internet.exampleEmail(),
password: faker.internet.password(),
username: faker.internet.userName(),
}
const {
data: { user, session },
error: signUpError,
} = await this.signUp(supabase, fakeUser)
expect(signUpError).toBeNull()
expect(user).toBeDefined()
expect(user.email).toEqual(fakeUser.email.toLowerCase())
expect(session).toBeDefined()
const [createdUser] = await this.selectUser(user)
expect(createdUser.email).toEqual(fakeUser.email.toLowerCase())
}
@feature(FEATURE.AUTHENTICATION)
@severity(Severity.BLOCKER)
@description('When user sign up then he should not be logged in until he confirms his email')
@test
async 'sing up new user and sign in'() {
// sign up user
const supabase = this.createSupaClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY_ANON)
const fakeUser = {
email: faker.internet.exampleEmail(),
password: faker.internet.password(),
username: faker.internet.userName(),
}
const {
data: { user, session: emptySession },
error: signUpError,
} = await this.signUp(supabase, fakeUser)
expect(signUpError).toBeNull()
expect(user).toBeDefined()
expect(user.email).toEqual(fakeUser.email.toLowerCase())
expect(emptySession).not.toBeNull()
const {
data: { session },
error: signInError,
} = await supabase.auth.signInWithPassword({
email: fakeUser.email,
password: fakeUser.password,
})
expect(signInError).toBeNull()
expect(session).toBeDefined()
await supabase.auth.setSession(session)
// check if user is signed in
const {
data: [profile],
error: errorInsert,
} = await this.insertProfile(supabase, user, fakeUser)
expect(errorInsert).toBeNull()
expect(profile.username).toMatch(fakeUser.username)
const { data: profileGot } = await this.getUserProfile(supabase)
expect(profileGot.username).toMatch(profile.username)
// check if user is able to sign out
const { error } = await this.signOut(supabase)
expect(error).toBeNull()
}
@feature(FEATURE.AUTHENTICATION)
@severity(Severity.BLOCKER)
@description('When user sign up with phone then he should be logged in')
@test
async 'create new users by phone auth'() {
// sign up user
const supabase = this.createSupaClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY_ANON)
const fakeUser = {
password: faker.internet.password(),
username: faker.internet.userName(),
phone: faker.phone.phoneNumber('!#!##!######'),
}
const {
data: { user, session },
error: signUpError,
} = await this.signUpByPhone(supabase, fakeUser)
expect(signUpError).toBeNull()
expect(user).toBeDefined()
expect(user.phone).toEqual(fakeUser.phone)
expect(session).toBeDefined()
// check if user is signed in
const {
data: [profile],
error: errorInsert,
} = await this.insertProfile(supabase, user, fakeUser)
expect(errorInsert).toBeNull()
expect(profile.username).toMatch(fakeUser.username)
const { data: profileGot } = await this.getUserProfile(supabase)
expect(profileGot.username).toMatch(profile.username)
// check if user is able to sign out
const { error } = await this.signOut(supabase)
expect(error).toBeNull()
}
@feature(FEATURE.AUTHENTICATION)
@severity(Severity.BLOCKER)
@description('When user is already signed up then he should be able to log in')
@test
async 'existing users should be able to login'() {
// create user
const fakeUser = await this.createUser()
// sign in as user
const supabase = this.createSupaClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY_ANON)
const {
data: { session, user },
error: signInError,
} = await supabase.auth.signInWithPassword({
email: fakeUser.email,
password: fakeUser.password,
})
expect(signInError).toBeNull()
expect(session).toBeDefined()
expect(user).toBeDefined()
expect(user.email).toEqual(fakeUser.email.toLowerCase())
// check if user is signed in correctly and rls is working
const {
data: [profileInserted],
error: errorInsert,
} = await this.insertProfile(supabase, user, fakeUser)
expect(errorInsert).toBeNull()
expect(profileInserted.username).toMatch(fakeUser.username)
const { data: profileGot } = await this.getUserProfile(supabase)
expect(profileGot.username).toMatch(profileInserted.username)
// check if user is able to sign out
const { error } = await this.signOut(supabase)
expect(error).toBeNull()
}
@feature(FEATURE.AUTHENTICATION)
@severity(Severity.NORMAL)
@description('When user is signed in then he should be able to get his info and metadata')
@test
async 'get user should return logged in user'() {
// create user
const username = faker.internet.userName()
const date = faker.date.recent().toUTCString()
const fakeUser = await this.createUser({
username: username,
date: date,
})
// sign in as user
const supabase = this.createSupaClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY_ANON)
await supabase.auth.signInWithPassword({
email: fakeUser.email,
password: fakeUser.password,
})
// get signed in user data
const {
data: { user },
error: getUserErr,
} = await this.getUser(supabase)
log('Check if user is signed in correctly and can get his data')
expect(getUserErr).toBeNull()
expect(user).not.toBeNull()
expect(user.email).toEqual(fakeUser.email.toLowerCase())
expect(user.role).toEqual('authenticated')
expect(user.aud).toEqual('authenticated')
// verify if metadata is correctly set after sing up
expect(user.user_metadata).toEqual({
username: username,
date: date,
})
}
@feature(FEATURE.AUTHENTICATION)
@severity(Severity.NORMAL)
@description('When user is signed in then he should be able update himself in auth schema')
@test.skip
async 'update user should update logged in user'() {
// create user
const fakeUser = await this.createUser()
// sign in as user
const supabase = this.createSupaClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY_ANON)
await supabase.auth.signInWithPassword({
email: fakeUser.email,
password: fakeUser.password,
})
// get signed in user data
const user = await this.getUser(supabase)
// update user
const updParams = {
email: faker.internet.email(),
password: faker.internet.password(),
phone: faker.phone.phoneNumber('!#!##!######'),
}
const {
data: { user: updUser },
error: updUserError,
} = await this.updateUser(supabase, updParams)
expect(updUserError).toBeNull()
expect(updUser).not.toBeNull()
expect(updUser.email).toEqual(updParams.email.toLowerCase())
expect(updUser.phone).toEqual(updParams.phone)
// get user and check it was updated
const updatedUser = await this.getUser(supabase)
expect(updatedUser.data.user.email).toEqual(updParams.email.toLowerCase())
expect(updatedUser.data.user.phone).toEqual(updParams.phone)
// sign in with new credentials
await supabase.auth.signOut()
const signIn = await supabase.auth.signInWithPassword({
email: updParams.email,
password: updParams.password,
})
expect(signIn.error).toBeNull()
}
@feature(FEATURE.AUTHENTICATION)
@severity(Severity.NORMAL)
@description('When user changes session then he still should be correctly logined')
@test
async 'set session should set new auth'() {
// create user
const fakeUser = await this.createUser()
// sign in as user
const sb = this.createSupaClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY_ANON)
const {
data: { session },
} = await sb.auth.signInWithPassword({
email: fakeUser.email,
password: fakeUser.password,
})
const supabase = this.createSupaClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY_ANON)
const { error: sessionErr } = await supabase.auth.setSession(session)
expect(sessionErr).toBeNull()
// check if user is signed in correctly and rls is working
const { data: profileInserted, error: errorInsert } = await this.insertProfile(
supabase,
fakeUser,
fakeUser
)
expect(errorInsert).toBeNull()
expect(profileInserted).toHaveLength(1)
expect(profileInserted[0].username).toMatch(fakeUser.username)
}
@feature(FEATURE.AUTHENTICATION)
@severity(Severity.NORMAL)
@description('When user subscribes on auth changes then user has to receive auth updates')
@test
async 'on auth state changed should return events'() {
// create user
const fakeUser = await this.createUser()
const events: { event: AuthChangeEvent; token: string }[] = []
const onAuthStateChanged = (event: AuthChangeEvent, session: Session) => {
log('onAuthStateChanged triggered', event)
events.push({ event, token: session?.access_token })
}
// create client and subscribe on auth state changes
const supabase = this.createSupaClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY_ANON)
const {
data: { subscription },
} = supabase.auth.onAuthStateChange(onAuthStateChanged)
// sign in as user
await supabase.auth.signInWithPassword({
email: fakeUser.email,
password: fakeUser.password,
})
// update user
const updParams = {
email: faker.internet.email(),
password: faker.internet.password(),
phone: faker.phone.phoneNumber('!#!##!######'),
}
const { error: updUserError } = await this.updateUser(supabase, updParams)
expect(updUserError).toBeNull()
// remove subscription and sign out
subscription.unsubscribe()
await supabase.auth.signOut()
// check if sign in and update events were triggered and sign out event was not triggered
expect(events).toHaveLength(2)
expect(events.map((e) => e.event)).toEqual(
expect.arrayContaining(['SIGNED_IN', 'USER_UPDATED'])
)
expect(events.map((e) => e.event)).not.toContain('SIGNED_OUT')
}
}