Open ErinTran15 opened 10 months ago
Hi! Mocking is generally a bit harder to accomplish inside of the module, as everyone has different session data. The way we handled it internally is as follows:
1.) Inside of /tests/mock/setup.ts
we created a new "mocked" version of nuxt-auth
:
import { createResolver, defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup: (_options, nuxt) => {
const { resolve } = createResolver(import.meta.url)
const pathToMocks = resolve('./nuxt-auth.ts')
nuxt.hook('imports:extend', (_imports) => {
_imports.push({ name: 'useAuth', from: pathToMocks })
})
nuxt.hook('nitro:config', (nitroConfig) => {
if (!nitroConfig.alias) {
throw new Error('Alias must exist at this point, otherwise server-side cannot be mocked')
}
nitroConfig.alias['#auth'] = pathToMocks
})
},
})
/tests/mock/nuxt-auth.ts
import { eventHandler } from 'h3'
export const MOCKED_USER = { user: { role: 'admin', email: 'test@example.com', name: 'John Doe' } }
// App-side mocks
export const useAuth = () => ({
data: ref(MOCKED_USER),
status: ref('authenticated'),
getSession: () => MOCKED_USER,
signOut: () => {},
})
// Server-side mocks
export const getServerSession = () => MOCKED_USER
export const NuxtAuthHandler = () => eventHandler(() => MOCKED_USER)
nuxt.config.ts
we check if the environment is currently a test, environment. If it is we add this new mocked module into our modules array:const mockAuthModule = process.env.VITEST ? ['./test/mock/setup.ts'] : []
export default defineNuxtConfig({
modules: [
'@sidebase/nuxt-auth',
...mockAuthModule,
],
}
When running the application in ViTest, the mocked module will overwrite the real NuxtAuth module. This will result in a console warning that the composables are being overwritten, which is fine, as the mock will then work!
If we want to integrate this functionality into the module itself, I only see one issue: How do we allow people to define their own session data, as everyones session datatype can be different (also between providers). However I hope this quick overview helps you!
That's a great summary @zoey-kaiser.
Few suggestions:
useAuth
import on the client side is to use mockNuxtImport
I managed to get it to work with Cypress a while back. Maybe this can be useful information for the Vitest implementation.
Created a class to generate a token which then will be set within the cookies (next-auth.session-token
), which is used within the sidebase package.
The token includes the provided user information, which can be extracted within your tests. I used it to specify permissions to test them 😄 .
Note that the user secret should be the same as your configured secret within sidebase.
import { EncryptJWT, type JWTPayload } from 'jose';
import hkdf from '@panva/hkdf';
import User from './User';
export default class Session {
user: User;
secret: string;
accessToken: string;
expires: Date;
constructor (secret: string, user?: User) {
this.secret = secret;
this.user = user || new User();
// Set the expiration date to 1 year from now
this.expires = new Date(Date.now() + 365 * 24 * 60 * 60 * 1000);
}
private getDerivedEncryptionKey () {
return hkdf(
'sha256',
this.secret,
'',
'NextAuth.js Generated Encryption Key',
32,
);
}
private async encode (token: JWTPayload) {
const maxAge = 30 * 24 * 60 * 60; // 30 days
const encryptionSecret = await this.getDerivedEncryptionKey();
return new EncryptJWT(token)
.setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })
.setIssuedAt()
.setExpirationTime(Math.round(Date.now() / 1000 + maxAge))
.setJti('cypress-test')
.encrypt(encryptionSecret);
}
async generateAccessToken () {
this.accessToken = await this.encode({ user: this.user });
}
}
Lets add a section to the documentation this these examples!
@zoey-kaiser Where can I fine this information in the documentation?
Hi @pablo-vega-kloeckner-i 👋
We currently do not have any documentation on this, as we are currently rewriting the entire docs (https://github.com/sidebase/docs/pull/180). However, I have outlined our vitest setup in this comment: https://github.com/sidebase/nuxt-auth/issues/596#issuecomment-1864222564
If you have any additional questions to this, feel free to ask them here 😊
Environment
No response
Reproduction
No response
Describe the bug
I've been trying to do vi.mock and unplugin-auto-import to mock it but none of them works when I config it in unplugin-auto-import in vitest.config.ts like this
surely it won't work because its the wrong path but when I import it with the correct path like in auto import path it will give me error:
Missing "./dist/runtime/composables/authjs/useAuth" specifier in "@sidebase/nuxt-auth" package
pls is there any other ways I could mock it ? Really appreciate if you guys can help me
Additional context
No response
Logs
No response