cms.c2sgmbh/tests/unit/youtube/oauth-scopes.unit.spec.ts
Martin Porwoll 097bc5225c feat(youtube): add upload and analytics OAuth scopes
Add youtube.upload and yt-analytics.readonly scopes to enable video
uploading and analytics data retrieval in the YouTube Operations Hub.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 13:19:23 +00:00

75 lines
2.3 KiB
TypeScript

/**
* YouTube OAuth Scopes Unit Tests
*
* Verifies that all required OAuth scopes are present in the YouTube OAuth configuration,
* including upload and analytics scopes needed for the YouTube Operations Hub.
*/
import { describe, it, expect, vi } from 'vitest'
vi.mock('googleapis', () => {
class MockOAuth2 {
generateAuthUrl({ scope }: { scope: string[] }): string {
return `https://accounts.google.com/o/oauth2/v2/auth?scope=${encodeURIComponent(scope.join(' '))}`
}
}
return {
google: {
auth: {
OAuth2: MockOAuth2,
},
},
}
})
vi.stubEnv('YOUTUBE_CLIENT_ID', 'test-client-id')
vi.stubEnv('YOUTUBE_CLIENT_SECRET', 'test-client-secret')
vi.stubEnv('YOUTUBE_REDIRECT_URI', 'https://test.example.com/api/youtube/callback')
describe('YouTube OAuth Scopes', () => {
it('should include youtube.readonly scope', async () => {
vi.resetModules()
const { getAuthUrl } = await import('@/lib/integrations/youtube/oauth')
const url = getAuthUrl()
expect(url).toContain('youtube.readonly')
})
it('should include youtube.force-ssl scope', async () => {
vi.resetModules()
const { getAuthUrl } = await import('@/lib/integrations/youtube/oauth')
const url = getAuthUrl()
expect(url).toContain('youtube.force-ssl')
})
it('should include youtube scope (full access)', async () => {
vi.resetModules()
const { getAuthUrl } = await import('@/lib/integrations/youtube/oauth')
const url = getAuthUrl()
expect(url).toContain('auth%2Fyoutube')
})
it('should include youtube.upload scope', async () => {
vi.resetModules()
const { getAuthUrl } = await import('@/lib/integrations/youtube/oauth')
const url = getAuthUrl()
expect(url).toContain('youtube.upload')
})
it('should include yt-analytics.readonly scope', async () => {
vi.resetModules()
const { getAuthUrl } = await import('@/lib/integrations/youtube/oauth')
const url = getAuthUrl()
expect(url).toContain('yt-analytics.readonly')
})
it('should contain exactly 5 scopes', async () => {
vi.resetModules()
const { getAuthUrl } = await import('@/lib/integrations/youtube/oauth')
const url = getAuthUrl()
const decodedUrl = decodeURIComponent(url)
const scopeParam = decodedUrl.split('scope=')[1]
const scopes = scopeParam.split(' ')
expect(scopes).toHaveLength(5)
})
})