Skip to content

Commit

Permalink
docs: API docs for file endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
DafyddLlyr committed Nov 14, 2023
1 parent 00d7f0c commit 7ff5fcc
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 7 deletions.
7 changes: 7 additions & 0 deletions api.planx.uk/docs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ const securitySchemes = {
scheme: "bearer",
bearerFormat: "JWT",
},
fileAPIKeyAuth: {
type: "apiKey",
in: "header",
name: "api-key",
description:
"API key granted to third-party integration partners to access files uploaded by users as part of their application",
},
hasuraAuth: {
type: "apiKey",
in: "header",
Expand Down
4 changes: 2 additions & 2 deletions api.planx.uk/modules/file/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export type DownloadController = ValidatedRequestHandler<
>;

export const publicDownloadController: DownloadController = async (
req,
_req,
res,
next,
) => {
Expand All @@ -99,7 +99,7 @@ export const publicDownloadController: DownloadController = async (
};

export const privateDownloadController: DownloadController = async (
req,
_req,
res,
next,
) => {
Expand Down
99 changes: 99 additions & 0 deletions api.planx.uk/modules/file/docs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
openapi: 3.1.0
info:
title: Plan✕ API
version: 0.1.0
tags:
- name: file
description: Endpoints for uploading and downloading files
components:
parameters:
fileKey:
in: path
name: fileKey
type: string
required: true
fileName:
in: path
name: fileName
type: string
required: true
schemas:
UploadFile:
type: object
properties:
filename:
type: string
required: true
file:
type: string
format: binary
responses:
UploadFile:
type: object
properties:
fileType:
oneOf:
- type: string
- type: "null"
fileUrl:
type: string
DownloadFile:
description: Successful response
content:
application/octet-stream:
schema:
type: string
format: binary
paths:
/file/private/upload:
post:
tags: ["file"]
security:
- bearerAuth: []
requestBody:
content:
multipart/form-data:
schema:
$ref: "#/components/schemas/UploadFile"
responses:
"200":
$ref: "#/components/responses/UploadFile"
"500":
$ref: "#/components/responses/ErrorMessage"
/file/public/upload:
post:
tags: ["file"]
requestBody:
content:
multipart/form-data:
schema:
$ref: "#/components/schemas/UploadFile"
responses:
"200":
$ref: "#/components/responses/UploadFile"
"500":
$ref: "#/components/responses/ErrorMessage"
/file/public/{fileKey}/{fileName}:
get:
tags: ["file"]
parameters:
- $ref: "#/components/parameters/fileKey"
- $ref: "#/components/parameters/fileName"
responses:
"200":
$ref: "#/components/responses/DownloadFile"
"500":
$ref: "#/components/responses/ErrorMessage"
/file/private/{fileKey}/{fileName}:
get:
tags: ["file"]
parameters:
- $ref: "#/components/parameters/fileKey"
- $ref: "#/components/parameters/fileName"
security:
- fileAPIKeyAuth: []
responses:
"200":
$ref: "#/components/responses/DownloadFile"
"500":
$ref: "#/components/responses/ErrorMessage"
17 changes: 17 additions & 0 deletions api.planx.uk/modules/file/file.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import supertest from "supertest";

import app from "../../server";
import { deleteFilesByURL } from "./service/deleteFile";
import { authHeader } from "../../tests/mockJWT";

let mockPutObject: jest.Mocked<() => void>;
let mockGetObject: jest.Mocked<() => void>;
Expand Down Expand Up @@ -42,10 +43,23 @@ describe("File upload", () => {

describe("Private", () => {
const ENDPOINT = "/file/private/upload";
const auth = authHeader({ role: "teamEditor" });

it("returns an error if authorization headers are not set", async () => {
await supertest(app)
.post("/flows/1/move/new-team")
.expect(401)
.then((res) => {
expect(res.body).toEqual({
error: "No authorization token was found",
});
});
});

it("should not upload without filename", async () => {
await supertest(app)
.post(ENDPOINT)
.set(auth)
.field("filename", "")
.attach("file", Buffer.from("some data"), "some_file.txt")
.expect(400)
Expand All @@ -59,6 +73,7 @@ describe("File upload", () => {
it("should not upload without file", async () => {
await supertest(app)
.post(ENDPOINT)
.set(auth)
.field("filename", "some filename")
.expect(500)
.then((res) => {
Expand All @@ -70,6 +85,7 @@ describe("File upload", () => {
it("should upload file", async () => {
await supertest(app)
.post(ENDPOINT)
.set(auth)
.field("filename", "some_file.txt")
.attach("file", Buffer.from("some data"), "some_file.txt")
.then((res) => {
Expand All @@ -91,6 +107,7 @@ describe("File upload", () => {

await supertest(app)
.post("/file/private/upload")
.set(auth)
.field("filename", "some_file.txt")
.attach("file", Buffer.from("some data"), "some_file.txt")
.expect(500)
Expand Down
11 changes: 6 additions & 5 deletions api.planx.uk/modules/file/routes.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Router } from "express";

import multer from "multer";
import { useFilePermission } from "../auth/middleware";
import { useFilePermission, useTeamEditorAuth } from "../auth/middleware";
import {
downloadFileSchema,
privateDownloadController,
Expand All @@ -15,17 +15,18 @@ import { validate } from "../../shared/middleware/validate";
const router = Router();

router.post(
"/private/upload",
"/public/upload",
multer().single("file"),
validate(uploadFileSchema),
privateUploadController,
publicUploadController,
);

router.post(
"/public/upload",
"/private/upload",
multer().single("file"),
useTeamEditorAuth,
validate(uploadFileSchema),
publicUploadController,
privateUploadController,
);

router.get(
Expand Down

0 comments on commit 7ff5fcc

Please sign in to comment.