-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8218f36
commit e914db0
Showing
19 changed files
with
1,083 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
-- CreateTable | ||
CREATE TABLE "Item" ( | ||
"id" SERIAL NOT NULL, | ||
"name" VARCHAR(50) NOT NULL, | ||
"mimeType" VARCHAR(255) NOT NULL, | ||
"blobUrl" VARCHAR(1024) NOT NULL, | ||
"ownerId" INTEGER NOT NULL, | ||
"parentId" INTEGER, | ||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
"updatedAt" TIMESTAMP(3) NOT NULL, | ||
"deletedAt" TIMESTAMP(3), | ||
|
||
CONSTRAINT "Item_pkey" PRIMARY KEY ("id") | ||
); | ||
|
||
-- CreateIndex | ||
CREATE INDEX "Item_blobUrl_idx" ON "Item"("blobUrl"); | ||
|
||
-- CreateIndex | ||
CREATE INDEX "Item_ownerId_idx" ON "Item"("ownerId"); | ||
|
||
-- CreateIndex | ||
CREATE INDEX "Item_parentId_idx" ON "Item"("parentId"); | ||
|
||
-- CreateIndex | ||
CREATE INDEX "Item_ownerId_parentId_idx" ON "Item"("ownerId", "parentId"); | ||
|
||
-- CreateIndex | ||
CREATE INDEX "Item_deletedAt_idx" ON "Item"("deletedAt"); | ||
|
||
-- AddForeignKey | ||
ALTER TABLE "Item" ADD CONSTRAINT "Item_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE "Item" ADD CONSTRAINT "Item_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "Item"("id") ON DELETE SET NULL ON UPDATE CASCADE; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
import { User } from '@prisma/client'; | ||
import UserService from '../../auth/user.service'; | ||
import AuthService from '../../auth/auth.service'; | ||
|
||
describe('POST /api/item', () => { | ||
let userService: UserService; | ||
let authService: AuthService; | ||
|
||
let user: User; | ||
|
||
beforeAll(async () => { | ||
authService = new AuthService(); | ||
userService = new UserService(); | ||
|
||
user = await userService.createUser({ | ||
name: 'Joe Biden the 1st', | ||
email: '[email protected]', | ||
password: '1234', | ||
}); | ||
}); | ||
|
||
/* | ||
* Generate client token tests | ||
*/ | ||
|
||
it('should return status 200 and return a new clientToken', async () => { | ||
const { accessToken } = await authService.createTokens(user.id); | ||
|
||
const response = await global.fastify.inject({ | ||
method: 'POST', | ||
url: '/api/item', | ||
headers: { | ||
'content-type': 'text/plain', | ||
authorization: 'Bearer ' + accessToken, | ||
}, | ||
payload: { | ||
type: 'blob.generate-client-token', | ||
payload: { | ||
callbackUrl: 'https://example.com/api/item', | ||
clientPayload: JSON.stringify({ parentId: null }), | ||
pathname: 'test.txt', | ||
}, | ||
}, | ||
}); | ||
|
||
expect(response.statusCode).toBe(200); | ||
expect(response.json()).toEqual({ | ||
type: 'blob.generate-client-token', | ||
clientToken: expect.any(String), | ||
}); | ||
}); | ||
|
||
it('should return status 401, when unauthorized', async () => { | ||
const response = await global.fastify.inject({ | ||
method: 'POST', | ||
url: '/api/item', | ||
headers: { | ||
'content-type': 'text/plain', | ||
authorization: 'invalid_access_token!!!', | ||
}, | ||
payload: { | ||
type: 'blob.generate-client-token', | ||
payload: { | ||
callbackUrl: 'https://example.com/api/item', | ||
clientPayload: JSON.stringify({ parentId: null }), | ||
pathname: 'test.txt', | ||
}, | ||
}, | ||
}); | ||
|
||
expect(response.statusCode).toBe(401); | ||
expect(response.json()).toEqual({ | ||
error: 'Unauthorized', | ||
message: 'Unauthorized', | ||
statusCode: 401, | ||
}); | ||
}); | ||
|
||
it('should return status 400, when clientPayload is missing', async () => { | ||
const { accessToken } = await authService.createTokens(user.id); | ||
|
||
const response = await global.fastify.inject({ | ||
method: 'POST', | ||
url: '/api/item', | ||
headers: { | ||
'content-type': 'text/plain', | ||
authorization: 'Bearer ' + accessToken, | ||
}, | ||
payload: { | ||
type: 'blob.generate-client-token', | ||
payload: { | ||
callbackUrl: 'https://example.com/api/item', | ||
pathname: 'test.txt', | ||
}, | ||
}, | ||
}); | ||
|
||
expect(response.statusCode).toBe(400); | ||
expect(response.json()).toEqual({ | ||
error: 'Bad Request', | ||
message: 'No clientPayload was passed!', | ||
statusCode: 400, | ||
}); | ||
}); | ||
|
||
it('should return status 400, when clientPayload.parentId is missing', async () => { | ||
const { accessToken } = await authService.createTokens(user.id); | ||
|
||
const response = await global.fastify.inject({ | ||
method: 'POST', | ||
url: '/api/item', | ||
headers: { | ||
'content-type': 'text/plain', | ||
authorization: 'Bearer ' + accessToken, | ||
}, | ||
payload: { | ||
type: 'blob.generate-client-token', | ||
payload: { | ||
callbackUrl: 'https://example.com/api/item', | ||
clientPayload: JSON.stringify({}), | ||
pathname: 'test.txt', | ||
}, | ||
}, | ||
}); | ||
|
||
expect(response.statusCode).toBe(400); | ||
expect(response.json()).toEqual({ | ||
error: 'Bad Request', | ||
message: 'clientPayload.parentId is required!', | ||
statusCode: 400, | ||
}); | ||
}); | ||
|
||
it('should return status 400, when providing invalid json string as payload', async () => { | ||
const { accessToken } = await authService.createTokens(user.id); | ||
|
||
const response = await global.fastify.inject({ | ||
method: 'POST', | ||
url: '/api/item', | ||
headers: { | ||
'content-type': 'text/plain', | ||
authorization: 'Bearer ' + accessToken, | ||
}, | ||
payload: 'Invalid json', | ||
}); | ||
|
||
expect(response.statusCode).toBe(400); | ||
expect(response.json()).toEqual({ | ||
error: 'Bad Request', | ||
message: expect.stringContaining('Unexpected token'), | ||
statusCode: 400, | ||
}); | ||
}); | ||
|
||
/* | ||
* Upload completed callback tests | ||
*/ | ||
|
||
it('should return status 400, when called without valid "x-vercel-signature" header', async () => { | ||
const response = await global.fastify.inject({ | ||
method: 'POST', | ||
url: '/api/item', | ||
headers: { | ||
'content-type': 'text/plain', | ||
}, | ||
payload: { | ||
type: 'blob.upload-completed', | ||
payload: { | ||
blob: { | ||
url: 'https://example.com/test-ihufsdihudsfuds.txt', | ||
pathname: 'test.txt', | ||
contentType: 'text/plain', | ||
contentDisposition: 'attachment; filename="test.txt"', | ||
}, | ||
tokenPayload: JSON.stringify({ parentId: null, ownerId: user.id }), | ||
}, | ||
}, | ||
}); | ||
|
||
expect(response.statusCode).toBe(400); | ||
expect(response.json()).toEqual({ | ||
error: 'Bad Request', | ||
message: 'Vercel Blob: Missing callback signature', | ||
statusCode: 400, | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.