Skip to content

Commit

Permalink
Merge branch 'main' into BC-5713-show-spinner
Browse files Browse the repository at this point in the history
  • Loading branch information
bischofmax authored Nov 6, 2023
2 parents 22092f2 + 62bc3f3 commit 1140e86
Show file tree
Hide file tree
Showing 50 changed files with 2,109 additions and 340 deletions.
47 changes: 19 additions & 28 deletions src/components/data-board/BoardApi.composable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import {
ContentElementType,
CreateCardBodyParamsRequiredEmptyElementsEnum,
CreateContentElementBodyParams,
ExternalToolElementResponse,
FileElementContent,
LinkElementContent,
RichTextElementContent,
ExternalToolElementContentBody,
FileElementContentBody,
LinkElementContentBody,
RichTextElementContentBody,
RoomsApiFactory,
SubmissionContainerElementContent,
SubmissionContainerElementContentBody,
} from "@/serverApi/v3";
import { AnyContentElement } from "@/types/board/ContentElement";
import { $axios, mapAxiosErrorToResponseError } from "@/utils/api";
Expand Down Expand Up @@ -73,51 +73,42 @@ export const useBoardApi = () => {
const generateDataProp = (element: AnyContentElement) => {
if (element.type === ContentElementType.RichText) {
return {
content: element.content as RichTextElementContent,
content: element.content,
type: element.type,
};
} as RichTextElementContentBody;
}

if (element.type === ContentElementType.File) {
return {
content: element.content as FileElementContent,
content: element.content,
type: ContentElementType.File,
};
} as FileElementContentBody;
}

if (element.type === ContentElementType.SubmissionContainer) {
return {
content: element.content as SubmissionContainerElementContent,
content: element.content,
type: ContentElementType.SubmissionContainer,
};
} as SubmissionContainerElementContentBody;
}

if (isExternalToolElement(element)) {
if (element.type === ContentElementType.Link) {
return {
content: {
contextExternalToolId:
element.content.contextExternalToolId ?? undefined,
},
type: ContentElementType.ExternalTool,
};
content: element.content,
type: ContentElementType.Link,
} as LinkElementContentBody;
}

if (element.type === ContentElementType.Link) {
if (element.type === ContentElementType.ExternalTool) {
return {
content: element.content as LinkElementContent,
type: ContentElementType.Link,
};
content: element.content,
type: ContentElementType.ExternalTool,
} as ExternalToolElementContentBody;
}

throw new Error("element.type mapping is undefined for updateElementCall");
};

const isExternalToolElement = (
element: AnyContentElement
): element is ExternalToolElementResponse => {
return element.type === ContentElementType.ExternalTool;
};

const createElementCall = async (
cardId: string,
params: CreateContentElementBodyParams
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
FileApiInterface,
FileRecordParentType,
FileRecordResponse,
FileUrlParams,
RenameFileParams,
} from "@/fileStorageApi/v3";
import { authModule } from "@/store/store-accessor";
Expand Down Expand Up @@ -65,6 +66,30 @@ export const useFileStorageApi = (
}
};

const uploadFromUrl = async (imageUrl: string): Promise<void> => {
try {
const { pathname } = new URL(imageUrl);
const fileName = pathname.substring(pathname.lastIndexOf("/") + 1);
const schoolId = authModule.getUser?.schoolId as string;
const fileUrlParams: FileUrlParams = {
url: imageUrl,
fileName,
headers: `User-Agent: Embed Request User Agent`,
};
const response = await fileApi.uploadFromUrl(
schoolId,
parentId,
parentType,
fileUrlParams
);

fileRecord.value = response.data;
} catch (error) {
showError(error);
throw error;
}
};

const rename = async (
fileRecordId: FileRecordResponse["id"],
params: RenameFileParams
Expand Down Expand Up @@ -110,6 +135,7 @@ export const useFileStorageApi = (
fetchFile,
rename,
upload,
uploadFromUrl,
fileRecord,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,104 @@ describe("FileStorageApi Composable", () => {
});
});

describe("uploadFromUrl", () => {
describe("when file api uploads file successfully", () => {
const setup = () => {
const fileName = "example-picture.jpg";
const imageUrl = `https://www.example.com/${fileName}`;
const parentId = ObjectIdMock();
const parentType = FileRecordParentType.BOARDNODES;
const fileRecordResponse = fileRecordResponseFactory.build({
parentId,
parentType,
name: fileName,
});
const response = {
data: fileRecordResponse,
};

const uploadFromUrlMock = jest.fn().mockResolvedValueOnce(response);
const { fileApiFactory } = setupFileStorageFactoryMock({
uploadFromUrlMock,
});
setupFileStorageNotifier();

return {
parentId,
parentType,
fileApiFactory,
fileRecordResponse,
fileName,
imageUrl,
};
};

it("should call FileApiFactory.uploadFromUrl", async () => {
const { parentId, parentType, fileApiFactory, fileName, imageUrl } =
setup();
const { uploadFromUrl } = useFileStorageApi(parentId, parentType);

await uploadFromUrl(imageUrl);

expect(fileApiFactory.uploadFromUrl).toBeCalledWith(
"schoolId",
parentId,
parentType,
expect.objectContaining({
url: imageUrl,
fileName,
})
);
});

it("should set filerecord", async () => {
const { parentId, parentType, imageUrl, fileRecordResponse } = setup();
const { uploadFromUrl, fileRecord } = useFileStorageApi(
parentId,
parentType
);

await uploadFromUrl(imageUrl);

expect(fileRecord.value).toBe(fileRecordResponse);
});
});

describe("when file api returns error", () => {
const setup = () => {
const parentId = ObjectIdMock();
const parentType = FileRecordParentType.BOARDNODES;
const file = new File([""], "filename");

const { responseError, expectedPayload } = setupErrorResponse(
ErrorType.FILE_TOO_BIG
);

mockedMapAxiosErrorToResponseError.mockReturnValue(expectedPayload);

const uploadFromUrlMock = jest.fn().mockRejectedValue(responseError);
setupFileStorageFactoryMock({ uploadFromUrlMock });
setupFileStorageNotifier();

return {
parentId,
parentType,
file,
responseError,
};
};

it("should call showFileTooBigError and pass error", async () => {
const { parentId, parentType, responseError } = setup();
const { uploadFromUrl } = useFileStorageApi(parentId, parentType);

await expect(uploadFromUrl("abc:/not-an-url")).rejects.toBe(
responseError
);
});
});
});

describe("rename", () => {
describe("when file api rename file successfully", () => {
const setup = () => {
Expand Down
65 changes: 0 additions & 65 deletions src/components/feature-board-link-element/LinkContentElement.vue

This file was deleted.

This file was deleted.

Loading

0 comments on commit 1140e86

Please sign in to comment.