Skip to content

Commit

Permalink
Merge pull request #11 from IslamZaoui/dev
Browse files Browse the repository at this point in the history
add unit testing & update CI workflow
  • Loading branch information
IslamZaoui authored Oct 10, 2024
2 parents 220b43c + db9c411 commit 27339f8
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 13 deletions.
11 changes: 7 additions & 4 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: CI/CD
name: CI

on:
push:
Expand All @@ -16,13 +16,16 @@ jobs:
- name: Set up bun
uses: oven-sh/setup-bun@v2
with:
bun-version: 1.1.29
bun-version: 1.1.30

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Run lint
run: bun lint

- name: Run build
run: bun run build
- name: Install playwright
run: bunx playwright install

- name: Run test
run: bun run test
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Publish
on:
workflow_run:
workflows: [CI/CD]
workflows: [CI]
branches: [main]
types: [completed]

Expand All @@ -22,7 +22,7 @@ jobs:
- name: Set up bun
uses: oven-sh/setup-bun@v2
with:
bun-version: 1.1.29
bun-version: 1.1.30

- name: Install Dependencies
run: bun install --frozen-lockfile
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Secure your [sveltekit](https://kit.svelte.dev/) app using [http response headers](https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html)

[![CI/CD](https://github.com/IslamZaoui/securekit/actions/workflows/lint.yaml/badge.svg)](https://github.com/IslamZaoui/securekit/actions/workflows/lint.yaml)
[![CI](https://github.com/IslamZaoui/securekit/actions/workflows/lint.yaml/badge.svg)](https://github.com/IslamZaoui/securekit/actions/workflows/lint.yaml)
[![NPM](https://img.shields.io/npm/v/%40islamzaoui%2Fsecurekit)](https://www.npmjs.com/package/@islamzaoui/securekit)
[![Issues](https://img.shields.io/github/issues/IslamZaoui/securekit)](https://github.com/IslamZaoui/securekit/issues)
[![License](https://img.shields.io/github/license/IslamZaoui/securekit)](https://github.com/IslamZaoui/securekit/blob/main/LICENSE)
Expand Down
1 change: 1 addition & 0 deletions apps/demo/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
test-results
node_modules

# Output
Expand Down
25 changes: 25 additions & 0 deletions apps/demo/e2e/headers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { expect, test } from '@playwright/test';

test('home page has expected headers', async ({ page }) => {
const response = await page.goto('/');
if (response) {
const headers = await response.allHeaders();
expect(headers).toHaveProperty('access-control-allow-origin');
expect(headers).toHaveProperty('content-security-policy');
expect(headers).toHaveProperty('permissions-policy');
expect(headers).toHaveProperty('x-content-type-options');
expect(headers).toHaveProperty('x-frame-options');
} else {
throw new Error('Failed to load the home page');
}
});

test('home page have removed headers', async ({ page }) => {
const response = await page.goto('/');
if (response) {
const headers = await response.allHeaders();
expect(headers).not.toHaveProperty('x-sveltekit-page');
} else {
throw new Error('Failed to load the home page');
}
});
4 changes: 3 additions & 1 deletion apps/demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --check . && eslint .",
"format": "prettier --write ."
"format": "prettier --write .",
"test": "playwright test"
},
"devDependencies": {
"@playwright/test": "^1.45.3",
"@sveltejs/adapter-vercel": "^5.4.4",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
Expand Down
10 changes: 10 additions & 0 deletions apps/demo/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineConfig } from '@playwright/test';

export default defineConfig({
webServer: {
command: 'bun run build && bun run preview',
port: 4173
},

testDir: 'e2e'
});
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
"scripts": {
"build": "turbo run build",
"dev": "turbo run dev",
"preview": "turbo run preview",
"test": "turbo run test",
"release": "turbo run build && changeset publish",
"lint": "prettier --check \"**/*.{json,md}\" && turbo run lint",
"format": "prettier --write \"**/*.{json,md}\" && turbo run format"
Expand All @@ -13,9 +15,9 @@
"apps/*"
],
"devDependencies": {
"@changesets/cli": "^2.27.8",
"prettier": "^3.1.1",
"turbo": "^2.1.2"
"@changesets/cli": "^2.27.9",
"prettier": "^3.3.3",
"turbo": "^2.1.3"
},
"packageManager": "[email protected].29"
"packageManager": "[email protected].30"
}
4 changes: 3 additions & 1 deletion packages/securekit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"lint": "tsc && prettier --check .",
"format": "prettier --write .",
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
"build": "tsup src/index.ts --format cjs,esm --dts"
"build": "tsup src/index.ts --format cjs,esm --dts",
"test": "bun test"
},
"keywords": [
"http",
Expand All @@ -25,6 +26,7 @@
"license": "MIT",
"description": "Secure your sveltekit app using http response security headers",
"devDependencies": {
"@types/bun": "^1.1.11",
"prettier": "^3.1.1",
"tsup": "^8.3.0",
"typescript": "^5.0.0"
Expand Down
61 changes: 61 additions & 0 deletions packages/securekit/test/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { expect, test } from 'bun:test';
import { combineCspHeaders } from '../src/utils/cspHelpers';
import {
normalizeHeaderValue,
normalizeCspValue,
} from '../src/utils/headerNormalizers';

test('combineCspHeaders should return null for both null inputs', () => {
expect(combineCspHeaders(null, null)).toBeNull();
});

test('combineCspHeaders should return newCsp when existingCsp is null', () => {
const newCsp = "default-src 'self'";
expect(combineCspHeaders(null, newCsp)).toBe(newCsp);
});

test('combineCspHeaders should return existingCsp when newCsp is null', () => {
const existingCsp = "default-src 'self'";
expect(combineCspHeaders(existingCsp, null)).toBe(existingCsp);
});

test('combineCspHeaders should combine two CSP headers', () => {
const existingCsp = "default-src 'self'; script-src 'unsafe-inline'";
const newCsp = "script-src 'self'; img-src 'none'";
const expectedCsp =
"default-src 'self'; script-src 'unsafe-inline' 'self'; img-src 'none'";
expect(combineCspHeaders(existingCsp, newCsp)).toBe(expectedCsp);
});

test('combineCspHeaders should handle duplicate directives correctly', () => {
const existingCsp = "default-src 'self'; script-src 'unsafe-inline'";
const newCsp = "script-src 'unsafe-inline' 'self'";
const expectedCsp = "default-src 'self'; script-src 'unsafe-inline' 'self'";
expect(combineCspHeaders(existingCsp, newCsp)).toBe(expectedCsp);
});

test('normalizeHeaderValue should return null for null input', () => {
expect(normalizeHeaderValue(null)).toBeNull();
});

test('normalizeHeaderValue should trim whitespace from string input', () => {
expect(normalizeHeaderValue(' test ')).toBe('test');
});

test('normalizeHeaderValue should join array of strings with a comma and space', () => {
expect(normalizeHeaderValue(['value1', 'value2'])).toBe('value1, value2');
});

test('normalizeHeaderValue should convert number to string', () => {
expect(normalizeHeaderValue(123)).toBe('123');
});

test('normalizeCspValue should trim whitespace from string input', () => {
expect(normalizeCspValue(' directive ')).toBe('directive');
});

test('normalizeCspValue should join array of strings with a space', () => {
expect(normalizeCspValue(['directive1', 'directive2'])).toBe(
'directive1 directive2',
);
});
8 changes: 8 additions & 0 deletions turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@
"tasks": {
"format": {},
"lint": {},
"test": {
"dependsOn": ["^build"],
"outputs": [".svelte-kit/**", ".vercel/output/**"]
},
"dev": {
"cache": false,
"persistent": true
},
"preview": {
"cache": false,
"persistent": true
},
"build": {
"dependsOn": ["^build"],
"outputs": [
Expand Down

0 comments on commit 27339f8

Please sign in to comment.