From c92a3143685178f996605732331c151a81dc4b93 Mon Sep 17 00:00:00 2001 From: Darshan Date: Sat, 13 Sep 2025 14:25:31 +0530 Subject: [PATCH 1/3] improved: tests, smaller backend docs repo dependency. --- package.json | 2 +- playwright.config.ts | 2 +- pnpm-lock.yaml | 10 +-- tests/redirects/api.test.ts | 75 +++++++++++++++++++ .../main.test.ts} | 4 +- {src/lib/utils => tests/unit}/clamp.test.ts | 4 +- tests/unit/specs.test.ts | 43 +++++++++++ {src/lib/utils => tests/unit}/toScale.test.ts | 4 +- .../utils => tests/unit}/withPrevious.test.ts | 3 +- tests/utils/constants.ts | 58 ++++++++++++++ vite.config.ts | 2 +- 11 files changed, 192 insertions(+), 15 deletions(-) create mode 100644 tests/redirects/api.test.ts rename tests/{redirects.test.ts => redirects/main.test.ts} (59%) rename {src/lib/utils => tests/unit}/clamp.test.ts (84%) create mode 100644 tests/unit/specs.test.ts rename {src/lib/utils => tests/unit}/toScale.test.ts (85%) rename {src/lib/utils => tests/unit}/withPrevious.test.ts (94%) create mode 100644 tests/utils/constants.ts diff --git a/package.json b/package.json index 2df14fd05d..8ca1f06e61 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "@appwrite.io/console": "^0.6.4", "@appwrite.io/pink": "~0.26.0", "@appwrite.io/pink-icons": "~0.26.0", - "@appwrite.io/repo": "github:appwrite/appwrite#1.8.x", + "@appwrite.io/repo": "github:appwrite/appwrite#attempt-small-size-for-website", "@eslint/compat": "^1.2.7", "@eslint/js": "^9.21.0", "@fingerprintjs/fingerprintjs": "^4.5.1", diff --git a/playwright.config.ts b/playwright.config.ts index 5e3803c2fc..243e1fd0f7 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -9,7 +9,7 @@ const config: PlaywrightTestConfig = { } }, fullyParallel: true, - testDir: 'tests', + testDir: 'tests/redirects', testMatch: /(.+\.)?(test|spec)\.[jt]s/, projects: [ { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4c170218a2..9ab056d25f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -28,8 +28,8 @@ importers: specifier: ~0.26.0 version: 0.26.0 '@appwrite.io/repo': - specifier: github:appwrite/appwrite#1.8.x - version: https://codeload.github.com/appwrite/appwrite/tar.gz/07a11aa15c164a9da4211db13bb7495cb7b7047f + specifier: github:appwrite/appwrite#attempt-small-size-for-website + version: https://codeload.github.com/appwrite/appwrite/tar.gz/3114f572df92cf45f5f24da07c98aac620111803 '@eslint/compat': specifier: ^1.2.7 version: 1.3.2(eslint@9.34.0(jiti@2.5.1)) @@ -295,8 +295,8 @@ packages: '@appwrite.io/pink@0.26.0': resolution: {integrity: sha512-iPeGE56pauzxuIXt15ZswjKCErwp3QdF3XOlJZfyYY7J2nirra85JNTL+3lWuFIf8yYWL7NbvCjhf8ig79TgwA==} - '@appwrite.io/repo@https://codeload.github.com/appwrite/appwrite/tar.gz/07a11aa15c164a9da4211db13bb7495cb7b7047f': - resolution: {tarball: https://codeload.github.com/appwrite/appwrite/tar.gz/07a11aa15c164a9da4211db13bb7495cb7b7047f} + '@appwrite.io/repo@https://codeload.github.com/appwrite/appwrite/tar.gz/3114f572df92cf45f5f24da07c98aac620111803': + resolution: {tarball: https://codeload.github.com/appwrite/appwrite/tar.gz/3114f572df92cf45f5f24da07c98aac620111803} version: 0.0.0 '@babel/runtime@7.28.3': @@ -4322,7 +4322,7 @@ snapshots: normalize.css: 8.0.1 the-new-css-reset: 1.11.3 - '@appwrite.io/repo@https://codeload.github.com/appwrite/appwrite/tar.gz/07a11aa15c164a9da4211db13bb7495cb7b7047f': {} + '@appwrite.io/repo@https://codeload.github.com/appwrite/appwrite/tar.gz/3114f572df92cf45f5f24da07c98aac620111803': {} '@babel/runtime@7.28.3': {} diff --git a/tests/redirects/api.test.ts b/tests/redirects/api.test.ts new file mode 100644 index 0000000000..cdb813c51a --- /dev/null +++ b/tests/redirects/api.test.ts @@ -0,0 +1,75 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { expect, test } from '@playwright/test'; +import { capitalize } from '$lib/utils/capitalize'; +import { Platform, Service, type Variant, VERSIONS } from '../utils/constants'; + +const latest = String(VERSIONS[0]); + +const specCache = new Map(); + +function specPath(variant: Variant) { + return path.resolve( + process.cwd(), + `/node_modules/@appwrite.io/repo/app/config/specs/open-api3-${latest}-${variant}.json` + ); +} + +function loadSpec(variant: Variant): any | null { + if (specCache.has(variant)) { + return specCache.get(variant)!; + } + + try { + const file = specPath(variant); + const raw = fs.readFileSync(file, 'utf8').replace(/^\uFEFF/, ''); + const parsed = JSON.parse(raw); + + specCache.set(variant, parsed); + return parsed; + } catch { + specCache.set(variant, null); + return null; + } +} + +function deriveServices(): string[] { + const seen = new Set(); + const variants: Variant[] = ['client', 'server']; + + for (const variant of variants) { + const spec = loadSpec(variant); + if (!spec?.paths) continue; + + for (const pathItem of Object.values(spec.paths)) { + for (const method of Object.keys(pathItem as string)) { + const operation = (pathItem as any)[method]; + const group = operation?.['x-appwrite']?.group; + if (typeof group === 'string' && group.length > 0) { + seen.add(group); + } + } + } + } + + if (seen.size === 0) { + Object.values(Service).forEach((s) => seen.add(s)); + } + + return Array.from(seen).sort(); +} + +const SERVICES: string[] = deriveServices(); +const PLATFORMS: string[] = Object.values(Platform); + +for (const platform of PLATFORMS) { + test.describe(`Latest \`${platform}\``, () => { + for (const service of SERVICES) { + test(`${capitalize(service)}`, async ({ page }) => { + const url = `/docs/references/cloud/${platform}/${service}`; + const response = await page.goto(url, { waitUntil: 'domcontentloaded' }); + expect(response?.ok()).toBeTruthy(); + }); + } + }); +} diff --git a/tests/redirects.test.ts b/tests/redirects/main.test.ts similarity index 59% rename from tests/redirects.test.ts rename to tests/redirects/main.test.ts index 34f26806f9..2a23280d01 100644 --- a/tests/redirects.test.ts +++ b/tests/redirects/main.test.ts @@ -1,9 +1,9 @@ import { expect, test } from '@playwright/test'; -import redirects from '../src/redirects.json' with { type: 'json' }; +import redirects from '../../src/redirects.json' with { type: 'json' }; redirects.forEach(({ link, redirect }) => { test(`redirected from ${link} to ${redirect} exists`, async ({ page }) => { - const response = await page.goto(redirect); + const response = await page.goto(link, { waitUntil: 'domcontentloaded' }); expect(response?.ok()).toBeTruthy(); }); diff --git a/src/lib/utils/clamp.test.ts b/tests/unit/clamp.test.ts similarity index 84% rename from src/lib/utils/clamp.test.ts rename to tests/unit/clamp.test.ts index 36df58a918..bc8646977d 100644 --- a/src/lib/utils/clamp.test.ts +++ b/tests/unit/clamp.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest'; -import { clamp } from './clamp'; -import type { TestCases } from './test'; +import { clamp } from '$lib/utils/clamp'; +import type { TestCases } from '$lib/utils/test'; const testCases: TestCases = [ { diff --git a/tests/unit/specs.test.ts b/tests/unit/specs.test.ts new file mode 100644 index 0000000000..d8c80fedc4 --- /dev/null +++ b/tests/unit/specs.test.ts @@ -0,0 +1,43 @@ +import { describe, expect, it } from 'vitest'; + +import path from 'node:path'; +import fs from 'node:fs/promises'; +import { VERSIONS, type Variant } from '../utils/constants'; + +export type Version = (typeof VERSIONS)[number]; + +const VARIANTS: Variant[] = ['client', 'server', 'console']; + +function getSpecPath(version: Version, variant: Variant): string { + return path.join( + process.cwd(), + `/node_modules/@appwrite.io/repo/app/config/specs/open-api3-${version}-${variant}.json` + ); +} + +async function readJSON(filePath: string): Promise { + const raw = await fs.readFile(filePath, 'utf8'); + return JSON.parse(raw.replace(/^\uFEFF/, '')); +} + +describe.each(VERSIONS)('OpenAPI specs validation for version %s', (version) => { + describe.each(VARIANTS)('%s variant', (variant) => { + it('spec file exists and is a valid OpenAPI 3 document', async () => { + const file = getSpecPath(version, variant); + + await expect(fs.access(file)).resolves.toBeUndefined(); + + const json = await readJSON(file); + + expect(json && typeof json === 'object').toBeTruthy(); + expect(typeof json.openapi).toBe('string'); + + expect(json.openapi.startsWith('3')).toBe(true); + + expect(json.info && typeof json.info.title === 'string').toBe(true); + expect(json.paths && typeof json.paths === 'object').toBe(true); + + expect(Object.keys(json.paths).length).toBeGreaterThan(0); + }); + }); +}); diff --git a/src/lib/utils/toScale.test.ts b/tests/unit/toScale.test.ts similarity index 85% rename from src/lib/utils/toScale.test.ts rename to tests/unit/toScale.test.ts index 8337a3329f..9a45162296 100644 --- a/src/lib/utils/toScale.test.ts +++ b/tests/unit/toScale.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest'; -import { toScale } from './toScale'; -import type { TestCases } from './test'; +import { toScale } from '$lib/utils/toScale'; +import type { TestCases } from '$lib/utils/test'; const testCases: TestCases = [ { diff --git a/src/lib/utils/withPrevious.test.ts b/tests/unit/withPrevious.test.ts similarity index 94% rename from src/lib/utils/withPrevious.test.ts rename to tests/unit/withPrevious.test.ts index 6c4d4c9f1e..aa30a5505a 100644 --- a/src/lib/utils/withPrevious.test.ts +++ b/tests/unit/withPrevious.test.ts @@ -1,6 +1,7 @@ import { describe, expect, test } from 'vitest'; -import { withPrevious } from './withPrevious'; + import { get } from 'svelte/store'; +import { withPrevious } from '$lib/utils/withPrevious'; describe('withPrevious', () => { test('Should retain previous value (number)', () => { diff --git a/tests/utils/constants.ts b/tests/utils/constants.ts new file mode 100644 index 0000000000..9ddb7c62d5 --- /dev/null +++ b/tests/utils/constants.ts @@ -0,0 +1,58 @@ +export type Variant = 'client' | 'server' | 'console'; + +export const VERSIONS = [ + '1.8.x', + '1.7.x', + '1.6.x', + '1.5.x', + '1.4.x', + '1.3.x', + '1.2.x', + '1.1.x', + '1.0.x', + '0.15.x' +] as const; + +export type Version = (typeof VERSIONS)[number]; + +export const Service = { + Account: 'account', + Avatars: 'avatars', + Databases: 'databases', + TablesDB: 'tablesDB', + Functions: 'functions', + Messaging: 'messaging', + Health: 'health', + Locale: 'locale', + Storage: 'storage', + Teams: 'teams', + Users: 'users', + Sites: 'sites', + Tokens: 'tokens' +} as const; + +export const Platform = { + ClientWeb: 'client-web', + ClientFlutter: 'client-flutter', + ClientReactNative: 'client-react-native', + ClientApple: 'client-apple', + ClientAndroidKotlin: 'client-android-kotlin', + ClientAndroidJava: 'client-android-java', + ClientGraphql: 'client-graphql', + ClientRest: 'client-rest', + ServerNodeJs: 'server-nodejs', + ServerPython: 'server-python', + ServerDart: 'server-dart', + ServerPhp: 'server-php', + ServerRuby: 'server-ruby', + ServerDotNet: 'server-dotnet', + ServerDeno: 'server-deno', + ServerGo: 'server-go', + ServerSwift: 'server-swift', + ServerKotlin: 'server-kotlin', + ServerJava: 'server-java', + ServerGraphql: 'server-graphql', + ServerRest: 'server-rest' +} as const; + +export type Platform = (typeof Platform)[keyof typeof Platform]; diff --git a/vite.config.ts b/vite.config.ts index 47173153c1..92a763c809 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -39,6 +39,6 @@ export default defineConfig({ reportCompressedSize: false }, test: { - include: ['src/**/*.{test,spec}.{js,ts}'] + include: ['tests/unit/**/*.{test,spec}.{js,ts}'] } }); From 21010edfafb6cc354d0287ea787e0f270cfbe79f Mon Sep 17 00:00:00 2001 From: Darshan Date: Sat, 13 Sep 2025 17:33:57 +0530 Subject: [PATCH 2/3] remove: excessive tests. --- tests/redirects/api.test.ts | 75 ------------------------------------- 1 file changed, 75 deletions(-) delete mode 100644 tests/redirects/api.test.ts diff --git a/tests/redirects/api.test.ts b/tests/redirects/api.test.ts deleted file mode 100644 index cdb813c51a..0000000000 --- a/tests/redirects/api.test.ts +++ /dev/null @@ -1,75 +0,0 @@ -import fs from 'node:fs'; -import path from 'node:path'; -import { expect, test } from '@playwright/test'; -import { capitalize } from '$lib/utils/capitalize'; -import { Platform, Service, type Variant, VERSIONS } from '../utils/constants'; - -const latest = String(VERSIONS[0]); - -const specCache = new Map(); - -function specPath(variant: Variant) { - return path.resolve( - process.cwd(), - `/node_modules/@appwrite.io/repo/app/config/specs/open-api3-${latest}-${variant}.json` - ); -} - -function loadSpec(variant: Variant): any | null { - if (specCache.has(variant)) { - return specCache.get(variant)!; - } - - try { - const file = specPath(variant); - const raw = fs.readFileSync(file, 'utf8').replace(/^\uFEFF/, ''); - const parsed = JSON.parse(raw); - - specCache.set(variant, parsed); - return parsed; - } catch { - specCache.set(variant, null); - return null; - } -} - -function deriveServices(): string[] { - const seen = new Set(); - const variants: Variant[] = ['client', 'server']; - - for (const variant of variants) { - const spec = loadSpec(variant); - if (!spec?.paths) continue; - - for (const pathItem of Object.values(spec.paths)) { - for (const method of Object.keys(pathItem as string)) { - const operation = (pathItem as any)[method]; - const group = operation?.['x-appwrite']?.group; - if (typeof group === 'string' && group.length > 0) { - seen.add(group); - } - } - } - } - - if (seen.size === 0) { - Object.values(Service).forEach((s) => seen.add(s)); - } - - return Array.from(seen).sort(); -} - -const SERVICES: string[] = deriveServices(); -const PLATFORMS: string[] = Object.values(Platform); - -for (const platform of PLATFORMS) { - test.describe(`Latest \`${platform}\``, () => { - for (const service of SERVICES) { - test(`${capitalize(service)}`, async ({ page }) => { - const url = `/docs/references/cloud/${platform}/${service}`; - const response = await page.goto(url, { waitUntil: 'domcontentloaded' }); - expect(response?.ok()).toBeTruthy(); - }); - } - }); -} From 1560527e64d30aa6934ee0ef0398c4693fd3a55f Mon Sep 17 00:00:00 2001 From: Darshan Date: Sat, 13 Sep 2025 17:36:29 +0530 Subject: [PATCH 3/3] lint. --- tests/utils/constants.ts | 42 ---------------------------------------- 1 file changed, 42 deletions(-) diff --git a/tests/utils/constants.ts b/tests/utils/constants.ts index 9ddb7c62d5..4f2bb0f17b 100644 --- a/tests/utils/constants.ts +++ b/tests/utils/constants.ts @@ -14,45 +14,3 @@ export const VERSIONS = [ ] as const; export type Version = (typeof VERSIONS)[number]; - -export const Service = { - Account: 'account', - Avatars: 'avatars', - Databases: 'databases', - TablesDB: 'tablesDB', - Functions: 'functions', - Messaging: 'messaging', - Health: 'health', - Locale: 'locale', - Storage: 'storage', - Teams: 'teams', - Users: 'users', - Sites: 'sites', - Tokens: 'tokens' -} as const; - -export const Platform = { - ClientWeb: 'client-web', - ClientFlutter: 'client-flutter', - ClientReactNative: 'client-react-native', - ClientApple: 'client-apple', - ClientAndroidKotlin: 'client-android-kotlin', - ClientAndroidJava: 'client-android-java', - ClientGraphql: 'client-graphql', - ClientRest: 'client-rest', - ServerNodeJs: 'server-nodejs', - ServerPython: 'server-python', - ServerDart: 'server-dart', - ServerPhp: 'server-php', - ServerRuby: 'server-ruby', - ServerDotNet: 'server-dotnet', - ServerDeno: 'server-deno', - ServerGo: 'server-go', - ServerSwift: 'server-swift', - ServerKotlin: 'server-kotlin', - ServerJava: 'server-java', - ServerGraphql: 'server-graphql', - ServerRest: 'server-rest' -} as const; - -export type Platform = (typeof Platform)[keyof typeof Platform];