Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BC-5434 - meta data endpoint #2876

Merged
merged 46 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
c565cc4
initial implementation of client side handling
hoeppner-dataport Oct 20, 2023
97cc873
fix: problem with element types
hoeppner-dataport Oct 20, 2023
cb39a09
chore: add menu
hoeppner-dataport Oct 20, 2023
fc801f5
chore: work on menu
hoeppner-dataport Oct 20, 2023
29bc0e6
Merge branch 'main' of github.com:hpi-schul-cloud/nuxt-client into BC…
hoeppner-dataport Oct 20, 2023
938bed6
fix: sonar cloud regex security concern
hoeppner-dataport Oct 20, 2023
e6cd512
fix: problem with basename being not available in js
hoeppner-dataport Oct 20, 2023
d91ded8
chore: increase font coverage
hoeppner-dataport Oct 20, 2023
45e76af
chore: fix focus handler
hoeppner-dataport Oct 23, 2023
5be2cff
refactor isLoading to be connected to imageUpload
hoeppner-dataport Oct 23, 2023
eff074c
chore: refactored filechecks to be composable
hoeppner-dataport Oct 23, 2023
298a933
Merge branch 'main' of github.com:hpi-schul-cloud/nuxt-client into BC…
hoeppner-dataport Oct 23, 2023
bcc6fac
chore: fix language strings
hoeppner-dataport Oct 23, 2023
9f7dd36
validate on submit
hoeppner-dataport Oct 23, 2023
8635cee
chore: show menu not only on hover
hoeppner-dataport Oct 23, 2023
fc21c2d
extract business logic from component
hoeppner-dataport Oct 23, 2023
c7212b4
refactor: logic
hoeppner-dataport Oct 23, 2023
de70b1b
fix: move down when several elements are new (see BC-5632)
hoeppner-dataport Oct 24, 2023
8aba636
chore: fix naming
hoeppner-dataport Oct 24, 2023
3afe947
use unified header component
hoeppner-dataport Oct 24, 2023
bdc2e8a
refactor upload handling
hoeppner-dataport Oct 24, 2023
4405cbd
fix: prevent element move during input
hoeppner-dataport Oct 24, 2023
280573b
fix: lineheight in multiline input
hoeppner-dataport Oct 24, 2023
c8dc1f4
fix: put menu back at the right place
hoeppner-dataport Oct 24, 2023
c3c3121
fix: pixel magic for menu positioning
hoeppner-dataport Oct 24, 2023
3af2a97
chore: test url.util
hoeppner-dataport Nov 1, 2023
aaca8c0
chore: add tests
hoeppner-dataport Nov 2, 2023
935eb0f
chore: add tests for LinkContentElementCreate
hoeppner-dataport Nov 3, 2023
33305c9
chore: add test for LinkContentElementDisplay
hoeppner-dataport Nov 3, 2023
29ebb75
chore: add test for metaTagExtractorApi.composable
hoeppner-dataport Nov 3, 2023
a506bd9
Merge branch 'main' of github.com:hpi-schul-cloud/nuxt-client into BC…
hoeppner-dataport Nov 3, 2023
959c93a
chore: removed redundand type definition
hoeppner-dataport Nov 3, 2023
fa88922
chore: fix test LinkContentElementCreate
hoeppner-dataport Nov 3, 2023
6146f0c
chore: add test for PreviewGenerator.composable
hoeppner-dataport Nov 3, 2023
1b3ab81
chore: remove redundant code
hoeppner-dataport Nov 3, 2023
0d16644
chore: fix sonarcloud detection in mock value
hoeppner-dataport Nov 3, 2023
7cc1a6c
chore: fix sonarcloud detection in mock value - part 2
hoeppner-dataport Nov 3, 2023
81c3813
Merge branch 'main' of github.com:hpi-schul-cloud/nuxt-client into BC…
hoeppner-dataport Nov 3, 2023
5095e2f
update generated api
hoeppner-dataport Nov 3, 2023
a3e8485
Merge branch 'main' of github.com:hpi-schul-cloud/nuxt-client into BC…
hoeppner-dataport Nov 6, 2023
d60b64c
improve onKeydown handling
hoeppner-dataport Nov 6, 2023
00c6071
chore: improve tests
hoeppner-dataport Nov 6, 2023
bc675d6
chore: improve method name
hoeppner-dataport Nov 6, 2023
74d9755
Merge branch 'main' of github.com:hpi-schul-cloud/nuxt-client into BC…
hoeppner-dataport Nov 6, 2023
32c1b75
chore: formatting change
hoeppner-dataport Nov 6, 2023
6d2b344
fix: lint error
hoeppner-dataport Nov 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading