diff --git a/Makefile b/Makefile index 947b3ca..d5f97e9 100644 --- a/Makefile +++ b/Makefile @@ -54,3 +54,8 @@ reset-database: coverage: @PORT=${TEST_PORT} AUTH_TOKEN=${TEST_TOKEN} ./test.sh > /dev/null 2> /dev/null @go tool covdata func -i=${COVERAGE_DIR} | grep total | awk '{print $$3}' + +coverage-report: + @PORT=${TEST_PORT} AUTH_TOKEN=${TEST_TOKEN} ./test.sh > /dev/null 2> /dev/null + @go tool covdata func -i=${COVERAGE_DIR} + diff --git a/client/index.html b/client/index.html index e4b78ea..c40196f 100644 --- a/client/index.html +++ b/client/index.html @@ -4,7 +4,7 @@ -
No Posts Found!
; @@ -39,7 +41,7 @@ export function PostsPage() { setPosts({ ...posts, posts: [...posts.posts, new_post] }); // send request - const response = await fetch(`${API_URL}/post/new`, { method: "POST", body: JSON.stringify(creatingPost), credentials: "include" }); + const response = await fetch(`${API_URL}/post/new`, { method: "POST", body: JSON.stringify({ ...creatingPost, author_id: user.user_id }), credentials: "include" }); const result = await response.json(); // update state? setLoading(false); diff --git a/client/vite.config.ts b/client/vite.config.ts index d0de7e9..b85cf20 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -3,6 +3,5 @@ import react from '@vitejs/plugin-react-swc' // https://vitejs.dev/config/ export default defineConfig({ - base: "/dev-blog-go", - plugins: [react()], + plugins: [react()], }) diff --git a/src/main.go b/src/main.go index 02570e6..26f4ddc 100644 --- a/src/main.go +++ b/src/main.go @@ -149,7 +149,7 @@ func AuthMiddleware(next http.Handler) http.Handler { } } // otherwise return 401 - http.Error(w, "Unauthorized", http.StatusUnauthorized) + utils.Unauthorized(w); return } diff --git a/test/tests/auth.test.ts b/test/tests/auth.test.ts index 4c82ede..584fe7c 100644 --- a/test/tests/auth.test.ts +++ b/test/tests/auth.test.ts @@ -1,6 +1,7 @@ import { describe, test, expect } from "bun:test"; import { AUTH_HEADERS } from "user"; + describe("auth tests", () => { test("invalid-token fails", async () => { const response = await fetch(`localhost:8080/auth/user`, { method: "GET", headers: { 'Auth-Token': "rubbish-token" } }); @@ -12,4 +13,31 @@ describe("auth tests", () => { expect(response).toBeTruthy(); expect(response.ok).toBeTrue(); }); + test("unauthorized-acces", async () => { + const unauth_routes = [ + ["GET", "/posts"], + ["GET", "/posts/coding"], + ["GET", "/post/test-post"], + ["POST", "/post/new"], + ["PUT", "/post/edit"], + ["DELETE", "/post/delete/1"], + ["GET", "/categories"], + ["POST", "/category/new"], + ["DELETE", "/category/delete/coding"], + ["PUT", "/post/tag"], + ["DELETE", "/post/tag"], + ["GET", "/tags"], + ["GET", "/tokens"], + ["POST", "/token/new"], + ["PUT", "/token/edit"], + ["DELETE", "/token/delete/1"] + ]; + for (const [method, path] of unauth_routes) { + const response = await fetch(`localhost:8080${path}`, { method }); + expect(response).toBeTruthy(); + expect(response.ok).toBeFalse(); + expect(response.status).toBe(401); + expect(response.statusText).toBe("Unauthorized"); + } + }) }); diff --git a/test/tests/tokens.test.ts b/test/tests/tokens.test.ts new file mode 100644 index 0000000..cd8d12d --- /dev/null +++ b/test/tests/tokens.test.ts @@ -0,0 +1,50 @@ +import { expect, test, describe } from "bun:test"; +import { AUTH_HEADERS } from "user"; + +const test_token = { + user_id: 1, + name: "New Test Token", + note: "Generated during tests", + enabled: true +} + +let token_id: number | null = null; +describe("tokens", () => { + test("create", async () => { + const response = await fetch("localhost:8080/token/new", { method: "POST", headers: AUTH_HEADERS, body: JSON.stringify(test_token) }); + expect(response).toBeTruthy(); + expect(response.ok).toBeTrue(); + const result = await response.json(); + expect(result).toBeTruthy(); + expect(result.id).toBeTruthy(); + token_id = result.id; + }) + test("update", async () => { + const response = await fetch("localhost:8080/token/edit", { method: "PUT", headers: AUTH_HEADERS, body: JSON.stringify({ ...test_token, id: token_id, name: "Updated Token" }) }); + expect(response).toBeTruthy(); + expect(response.ok).toBeTrue(); + }) + test("get", async () => { + const response = await fetch("localhost:8080/tokens", { method: "GET", headers: AUTH_HEADERS }); + expect(response).toBeTruthy(); + expect(response.ok).toBeTrue(); + const result = await response.json(); + expect(result).toBeTruthy(); + expect(Object.values(result).map((r: any) => r.name)).toContain("Updated Token"); + }) + test("delete", async () => { + const response = await fetch(`localhost:8080/token/delete/${token_id}`, { method: "DELETE", headers: AUTH_HEADERS }) + expect(response).toBeTruthy(); + expect(response.ok).toBeTrue(); + const get_response = await fetch("localhost:8080/tokens", { method: "GET", headers: AUTH_HEADERS }); + expect(get_response).toBeTruthy(); + expect(get_response.ok).toBeTrue(); + const result = await get_response.json(); + expect(Object.values(result).find((r: any) => r.name == "Updated Token")).toBeFalsy(); + }) + test("delete not-existant", async () => { + const response = await fetch(`localhost:8080/token/delete/${token_id}`, { method: "DELETE", headers: AUTH_HEADERS }) + expect(response).toBeTruthy(); + expect(response.ok).toBeFalse(); + }) +}); diff --git a/todo.md b/todo.md index 5d8c476..6631be7 100644 --- a/todo.md +++ b/todo.md @@ -86,7 +86,9 @@ # v0.9 - [ ] Expose API to third-party website, make sure it all works -- [ ] > 80% test coverage +- [ ] Add test coverage + - [x] Tokens + - [ ] Categories - [x] Deploy client on public-accessible - [x] Try Github pages since there's no need for a server