@tscircuit/fake-snippets 0.0.9 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bun-tests/fake-snippets-api/fixtures/get-test-server.ts +5 -0
- package/bun-tests/fake-snippets-api/routes/packages/update.test.ts +161 -0
- package/bun-tests/fake-snippets-api/routes/snippets/get.test.ts +49 -0
- package/bun-tests/fake-snippets-api/routes/snippets/update.test.ts +70 -28
- package/dist/bundle.js +253 -110
- package/fake-snippets-api/lib/db/db-client.ts +71 -2
- package/fake-snippets-api/lib/db/schema.ts +3 -0
- package/fake-snippets-api/routes/api/packages/update.ts +91 -0
- package/fake-snippets-api/routes/api/snippets/create.ts +12 -3
- package/fake-snippets-api/routes/api/snippets/get.ts +1 -1
- package/fake-snippets-api/routes/api/snippets/list.ts +3 -0
- package/fake-snippets-api/routes/api/snippets/update.ts +7 -1
- package/package.json +1 -1
- package/src/components/EditorNav.tsx +48 -0
- package/src/hooks/use-package-as-snippet.ts +3 -2
|
@@ -8,6 +8,7 @@ interface TestFixture {
|
|
|
8
8
|
url: string
|
|
9
9
|
server: any
|
|
10
10
|
axios: typeof defaultAxios
|
|
11
|
+
unauthenticatedAxios: typeof defaultAxios
|
|
11
12
|
db: DbClient
|
|
12
13
|
seed: ReturnType<typeof seedDatabase>
|
|
13
14
|
}
|
|
@@ -30,6 +31,9 @@ export const getTestServer = async (): Promise<TestFixture> => {
|
|
|
30
31
|
Authorization: `Bearer ${seed.account.account_id}`,
|
|
31
32
|
},
|
|
32
33
|
})
|
|
34
|
+
const unauthenticatedAxios = defaultAxios.create({
|
|
35
|
+
baseURL: url,
|
|
36
|
+
})
|
|
33
37
|
|
|
34
38
|
afterEach(async () => {
|
|
35
39
|
if (server && typeof server.stop === "function") {
|
|
@@ -41,6 +45,7 @@ export const getTestServer = async (): Promise<TestFixture> => {
|
|
|
41
45
|
url,
|
|
42
46
|
server,
|
|
43
47
|
axios,
|
|
48
|
+
unauthenticatedAxios,
|
|
44
49
|
db,
|
|
45
50
|
seed,
|
|
46
51
|
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { getTestServer } from "bun-tests/fake-snippets-api/fixtures/get-test-server"
|
|
2
|
+
import { expect, test } from "bun:test"
|
|
3
|
+
|
|
4
|
+
test("update package", async () => {
|
|
5
|
+
const { axios, db } = await getTestServer()
|
|
6
|
+
|
|
7
|
+
// First create a package
|
|
8
|
+
const packageResponse = await axios.post(
|
|
9
|
+
"/api/packages/create",
|
|
10
|
+
{
|
|
11
|
+
name: "test-package",
|
|
12
|
+
description: "Test Description",
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
headers: {
|
|
16
|
+
Authorization: "Bearer 1234",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
)
|
|
20
|
+
const packageId = packageResponse.data.package.package_id
|
|
21
|
+
|
|
22
|
+
// Update the package
|
|
23
|
+
const response = await axios.post(
|
|
24
|
+
"/api/packages/update",
|
|
25
|
+
{
|
|
26
|
+
package_id: packageId,
|
|
27
|
+
name: "updated-package",
|
|
28
|
+
description: "Updated Description",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
headers: {
|
|
32
|
+
Authorization: "Bearer 1234",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
expect(response.status).toBe(200)
|
|
38
|
+
expect(response.data.ok).toBe(true)
|
|
39
|
+
expect(response.data.package.name).toBe("testuser/updated-package")
|
|
40
|
+
expect(response.data.package.description).toBe("Updated Description")
|
|
41
|
+
|
|
42
|
+
// Verify the package was updated in the database
|
|
43
|
+
const updatedPackage = db.packages.find((p) => p.package_id === packageId)
|
|
44
|
+
expect(updatedPackage?.name).toBe("testuser/updated-package")
|
|
45
|
+
expect(updatedPackage?.description).toBe("Updated Description")
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
test("update package privacy settings", async () => {
|
|
49
|
+
const { axios, db } = await getTestServer()
|
|
50
|
+
|
|
51
|
+
// Create initial public package
|
|
52
|
+
const packageResponse = await axios.post(
|
|
53
|
+
"/api/packages/create",
|
|
54
|
+
{
|
|
55
|
+
name: "public-package",
|
|
56
|
+
description: "Public Package",
|
|
57
|
+
is_private: false,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
headers: {
|
|
61
|
+
Authorization: "Bearer 1234",
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
)
|
|
65
|
+
const packageId = packageResponse.data.package.package_id
|
|
66
|
+
|
|
67
|
+
// Update to make it private
|
|
68
|
+
const response = await axios.post(
|
|
69
|
+
"/api/packages/update",
|
|
70
|
+
{
|
|
71
|
+
package_id: packageId,
|
|
72
|
+
is_private: true,
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
headers: {
|
|
76
|
+
Authorization: "Bearer 1234",
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
expect(response.status).toBe(200)
|
|
82
|
+
expect(response.data.ok).toBe(true)
|
|
83
|
+
expect(response.data.package.is_private).toBe(true)
|
|
84
|
+
expect(response.data.package.is_public).toBe(false)
|
|
85
|
+
expect(response.data.package.is_unlisted).toBe(true) // Private packages should be unlisted
|
|
86
|
+
|
|
87
|
+
// Verify in database
|
|
88
|
+
const updatedPackage = db.packages.find((p) => p.package_id === packageId)
|
|
89
|
+
expect(updatedPackage?.is_private).toBe(true)
|
|
90
|
+
expect(updatedPackage?.is_public).toBe(false)
|
|
91
|
+
expect(updatedPackage?.is_unlisted).toBe(true)
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
test("update non-existent package", async () => {
|
|
95
|
+
const { axios } = await getTestServer()
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
await axios.post(
|
|
99
|
+
"/api/packages/update",
|
|
100
|
+
{
|
|
101
|
+
package_id: "non-existent-id",
|
|
102
|
+
name: "updated-name",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
headers: {
|
|
106
|
+
Authorization: "Bearer 1234",
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
)
|
|
110
|
+
throw new Error("Expected request to fail")
|
|
111
|
+
} catch (error: any) {
|
|
112
|
+
expect(error.status).toBe(404)
|
|
113
|
+
expect(error.data.error.error_code).toBe("package_not_found")
|
|
114
|
+
expect(error.data.error.message).toBe("Package not found")
|
|
115
|
+
}
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
test("update package without permission", async () => {
|
|
119
|
+
const { axios, db } = await getTestServer()
|
|
120
|
+
|
|
121
|
+
db.addPackage({
|
|
122
|
+
name: "Package3",
|
|
123
|
+
unscoped_name: "Package3",
|
|
124
|
+
owner_github_username: "user1",
|
|
125
|
+
creator_account_id: "creator1",
|
|
126
|
+
created_at: "2023-01-03T00:00:00Z",
|
|
127
|
+
updated_at: "2023-01-03T00:00:00Z",
|
|
128
|
+
description: "Description 3",
|
|
129
|
+
ai_description: "AI Description 3",
|
|
130
|
+
owner_org_id: "org1",
|
|
131
|
+
latest_version: "1.0.0",
|
|
132
|
+
license: "MIT",
|
|
133
|
+
is_source_from_github: true,
|
|
134
|
+
star_count: 0,
|
|
135
|
+
} as any)
|
|
136
|
+
|
|
137
|
+
const packageId = db.packages[0].package_id
|
|
138
|
+
|
|
139
|
+
// Try to update with different user
|
|
140
|
+
try {
|
|
141
|
+
await axios.post(
|
|
142
|
+
"/api/packages/update",
|
|
143
|
+
{
|
|
144
|
+
package_id: packageId,
|
|
145
|
+
name: "stolen-package",
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
headers: {
|
|
149
|
+
Authorization: "Bearer 5678", // Different user
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
)
|
|
153
|
+
throw new Error("Expected request to fail")
|
|
154
|
+
} catch (error: any) {
|
|
155
|
+
expect(error.status).toBe(403)
|
|
156
|
+
expect(error.data.error.error_code).toBe("forbidden")
|
|
157
|
+
expect(error.data.error.message).toBe(
|
|
158
|
+
"You don't have permission to update this package",
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
})
|
|
@@ -112,3 +112,52 @@ test("GET /api/snippets/get - should return snippet by unscoped_name and owner",
|
|
|
112
112
|
const responseBody = getResponse.data
|
|
113
113
|
expect(responseBody.ok).toBe(true)
|
|
114
114
|
})
|
|
115
|
+
|
|
116
|
+
test("GET /api/snippets/get - should not return snippet if snippet is private and user is unauthenticated", async () => {
|
|
117
|
+
const { axios, db, unauthenticatedAxios } = await getTestServer()
|
|
118
|
+
|
|
119
|
+
// First create a snippet
|
|
120
|
+
const snippet = {
|
|
121
|
+
unscoped_name: "test-package",
|
|
122
|
+
owner_name: "testuser",
|
|
123
|
+
code: "export const TestComponent = () => <div>Test</div>",
|
|
124
|
+
dts: "export declare const TestComponent: () => JSX.Element",
|
|
125
|
+
created_at: "2023-01-01T00:00:00Z",
|
|
126
|
+
updated_at: "2023-01-01T00:00:00Z",
|
|
127
|
+
name: "testuser/test-package",
|
|
128
|
+
snippet_type: "package",
|
|
129
|
+
description: "Test package",
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
db.addSnippet(snippet as any)
|
|
133
|
+
|
|
134
|
+
const createdSnippet = db.packages[0]
|
|
135
|
+
|
|
136
|
+
const updatedSnippet = await axios.post("/api/snippets/update", {
|
|
137
|
+
snippet_id: createdSnippet.package_id,
|
|
138
|
+
is_private: true,
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
expect(updatedSnippet.status).toBe(200)
|
|
142
|
+
expect(updatedSnippet.data.snippet.is_private).toBe(true)
|
|
143
|
+
expect(updatedSnippet.data.snippet.is_public).toBe(false)
|
|
144
|
+
|
|
145
|
+
// Get the snippet using name and owner
|
|
146
|
+
const getResponse = await axios.post("/api/snippets/get", {
|
|
147
|
+
snippet_id: createdSnippet.package_id,
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
expect(getResponse.status).toBe(200)
|
|
151
|
+
const responseBody = getResponse.data
|
|
152
|
+
expect(responseBody.ok).toBe(true)
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
await unauthenticatedAxios.post("/api/snippets/get", {
|
|
156
|
+
snippet_id: createdSnippet.package_id,
|
|
157
|
+
})
|
|
158
|
+
throw new Error("Expected request to fail")
|
|
159
|
+
} catch (error: any) {
|
|
160
|
+
expect(error.status).toBe(404)
|
|
161
|
+
expect(error.data.error.error_code).toBe("snippet_not_found")
|
|
162
|
+
}
|
|
163
|
+
})
|
|
@@ -7,7 +7,7 @@ test("update snippet", async () => {
|
|
|
7
7
|
// Add a test snippet
|
|
8
8
|
const snippet = {
|
|
9
9
|
unscoped_name: "TestSnippet",
|
|
10
|
-
owner_name: "
|
|
10
|
+
owner_name: "testuser",
|
|
11
11
|
code: "Original Content",
|
|
12
12
|
created_at: "2023-01-01T00:00:00Z",
|
|
13
13
|
updated_at: "2023-01-01T00:00:00Z",
|
|
@@ -23,19 +23,11 @@ test("update snippet", async () => {
|
|
|
23
23
|
// Update the snippet
|
|
24
24
|
const updatedCode = "Updated Content"
|
|
25
25
|
const updatedCompiledJs = "console.log('Updated Content')"
|
|
26
|
-
const response = await axios.post(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
compiled_js: updatedCompiledJs,
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
headers: {
|
|
35
|
-
Authorization: "Bearer 1234",
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
)
|
|
26
|
+
const response = await axios.post("/api/snippets/update", {
|
|
27
|
+
snippet_id: addedPackage.package_id,
|
|
28
|
+
code: updatedCode,
|
|
29
|
+
compiled_js: updatedCompiledJs,
|
|
30
|
+
})
|
|
39
31
|
|
|
40
32
|
expect(response.status).toBe(200)
|
|
41
33
|
expect(response.data.snippet.code).toBe(updatedCode)
|
|
@@ -56,19 +48,11 @@ test("update non-existent snippet", async () => {
|
|
|
56
48
|
const { axios } = await getTestServer()
|
|
57
49
|
|
|
58
50
|
try {
|
|
59
|
-
await axios.post(
|
|
60
|
-
"
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
compiled_js: "console.log('Updated Content')",
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
headers: {
|
|
68
|
-
Authorization: "Bearer 1234",
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
)
|
|
51
|
+
await axios.post("/api/snippets/update", {
|
|
52
|
+
snippet_id: "non-existent-id",
|
|
53
|
+
code: "Updated Content",
|
|
54
|
+
compiled_js: "console.log('Updated Content')",
|
|
55
|
+
})
|
|
72
56
|
// If the request doesn't throw an error, fail the test
|
|
73
57
|
expect(true).toBe(false)
|
|
74
58
|
} catch (error: any) {
|
|
@@ -83,7 +67,7 @@ test("update snippet with null compiled_js", async () => {
|
|
|
83
67
|
// Add a test snippet with compiled_js
|
|
84
68
|
const snippet = {
|
|
85
69
|
unscoped_name: "TestSnippet",
|
|
86
|
-
owner_name: "
|
|
70
|
+
owner_name: "testuser",
|
|
87
71
|
code: "Original Content",
|
|
88
72
|
created_at: "2023-01-01T00:00:00Z",
|
|
89
73
|
updated_at: "2023-01-01T00:00:00Z",
|
|
@@ -155,3 +139,61 @@ test("update snippet after create snippet", async () => {
|
|
|
155
139
|
expect(response.data.snippet.code).toBe(updatedCode)
|
|
156
140
|
expect(response.data.snippet.updated_at).not.toBe(createdSnippet.created_at)
|
|
157
141
|
})
|
|
142
|
+
|
|
143
|
+
test("update snippet visibility", async () => {
|
|
144
|
+
const { axios, db } = await getTestServer()
|
|
145
|
+
|
|
146
|
+
const snippet = {
|
|
147
|
+
unscoped_name: "TestSnippet",
|
|
148
|
+
code: "Test Content",
|
|
149
|
+
snippet_type: "package",
|
|
150
|
+
description: "Test Description",
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
await axios.post("/api/snippets/create", snippet)
|
|
154
|
+
|
|
155
|
+
const createdSnippet = db.packages[0]
|
|
156
|
+
|
|
157
|
+
const response = await axios.post(
|
|
158
|
+
"/api/snippets/update",
|
|
159
|
+
{
|
|
160
|
+
snippet_id: createdSnippet.package_id,
|
|
161
|
+
is_private: true,
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
headers: {
|
|
165
|
+
Authorization: `Bearer ${createdSnippet.creator_account_id}`,
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
expect(response.status).toBe(200)
|
|
171
|
+
expect(response.data.snippet.is_private).toBe(true)
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
test("update snippet visibility with unauthenticated user", async () => {
|
|
175
|
+
const { axios, db } = await getTestServer()
|
|
176
|
+
|
|
177
|
+
const snippet = {
|
|
178
|
+
unscoped_name: "TestSnippet",
|
|
179
|
+
code: "Test Content",
|
|
180
|
+
snippet_type: "package",
|
|
181
|
+
description: "Test Description",
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
db.addSnippet(snippet as any)
|
|
185
|
+
|
|
186
|
+
const createdSnippet = db.packages[0]
|
|
187
|
+
|
|
188
|
+
try {
|
|
189
|
+
await axios.post("/api/snippets/update", {
|
|
190
|
+
snippet_id: createdSnippet.package_id,
|
|
191
|
+
is_private: true,
|
|
192
|
+
})
|
|
193
|
+
} catch (error: any) {
|
|
194
|
+
expect(error.status).toBe(403)
|
|
195
|
+
expect(error.data.error.message).toBe(
|
|
196
|
+
"You don't have permission to update this snippet",
|
|
197
|
+
)
|
|
198
|
+
}
|
|
199
|
+
})
|