Skip to content

feat: Support use blob to createComponent #20

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

Merged
merged 8 commits into from
Sep 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 11 additions & 3 deletions source/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -799,14 +799,18 @@ export class Session {
/**
* Create component from *file* and add to server location.
*
* @param {File} The file object to upload.
* @param {Blob} The file object to upload.
* @param {?object} [options = {}] - Options
* @param {?string} options.name - Component name. Defaults get from file object.
* @param {?number} options.data - Component data. Defaults to {}.
* @return {Promise} Promise resolved with the response when creating
* Component and ComponentLocation.
*/
createComponent(file, options = {}) {
const normalizedFileName = normalizeString(file.name);
const normalizedFileName = normalizeString(options.name ?? file.name);
if (!normalizedFileName) {
throw new CreateComponentError("Component name is missing.");
}
const fileNameParts = splitFileExtension(normalizedFileName);
const defaultProgress = (progress) => progress;
const defaultAbort = () => {};
Expand All @@ -825,9 +829,13 @@ export class Session {
let headers;

const updateOnProgressCallback = (oEvent) => {
let progress = 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jsdom won't set request headers before request, cause onProgress never be called in test enviroment.


if (oEvent.lengthComputable) {
onProgress(parseInt((oEvent.loaded / oEvent.total) * 100, 10));
progress = parseInt((oEvent.loaded / oEvent.total) * 100, 10);
}

onProgress(progress);
};

logger.debug("Registering component and fetching upload metadata.");
Expand Down
100 changes: 57 additions & 43 deletions test/server.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { rest } from "msw";
import { setupServer } from "msw/node";
import fs from "fs/promises";
import { pick } from "lodash";
import querySchemas from "./fixtures/query_schemas.json";
import queryServerInformation from "./fixtures/query_server_information.json";
import getUploadMetadata from "./fixtures/get_upload_metadata.json";
Expand All @@ -27,55 +28,68 @@ const handlers = [
);
}
const body = await Promise.all(
req.body.map(async ({ action, expression, entity_type: entityType }) => {
switch (action) {
case "query_server_information":
return queryServerInformation;
case "query_schemas":
return querySchemas;
case "create":
// create are fetched from test/fixtures where the file name matches the full expression
return JSON.parse(
await fs.readFile(
req.body.map(
async ({
action,
expression,
entity_type: entityType,
entity_data: entityData,
}) => {
switch (action) {
case "query_server_information":
return queryServerInformation;
case "query_schemas":
return querySchemas;
case "create":
// create are fetched from test/fixtures where the file name matches the full expression
const createFixture = await fs.readFile(
`${__dirname}/fixtures/create_${entityType.toLowerCase()}.json`,
{
encoding: "utf-8",
}
)
);
case "delete":
return {
action: "delete",
data: true,
};
case "update":
// update are fetched from test/fixtures where the file name matches the full expression
return JSON.parse(
await fs.readFile(
`${__dirname}/fixtures/update_${entityType.toLowerCase()}.json`,
{
encoding: "utf-8",
}
)
);
case "query":
// queries are fetched from test/fixtures where the file name matches the full expression
return JSON.parse(
await fs.readFile(
`${__dirname}/fixtures/query_${expression
.toLowerCase()
.split(" ")
.join("_")}.json`,
{ encoding: "utf-8" }
)
);
case "get_upload_metadata":
return getUploadMetadata;
);
const response = JSON.parse(createFixture);
return {
...response,
data: {
...response.data,
...pick(entityData, ["id"]),
},
};
case "delete":
return {
action: "delete",
data: true,
};
case "update":
// update are fetched from test/fixtures where the file name matches the full expression
return JSON.parse(
await fs.readFile(
`${__dirname}/fixtures/update_${entityType.toLowerCase()}.json`,
{
encoding: "utf-8",
}
)
);
case "query":
// queries are fetched from test/fixtures where the file name matches the full expression
return JSON.parse(
await fs.readFile(
`${__dirname}/fixtures/query_${expression
.toLowerCase()
.split(" ")
.join("_")}.json`,
{ encoding: "utf-8" }
)
);
case "get_upload_metadata":
return getUploadMetadata;

default:
throw new Error("Action not supported by test server.");
default:
throw new Error("Action not supported by test server.");
}
}
})
)
);
return res(ctx.json(body));
}),
Expand Down
34 changes: 21 additions & 13 deletions test/test_session.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,12 +295,11 @@ describe("Session", () => {

it("Should support uploading files", (done) => {
const data = { foo: "bar" };
const blob = new Blob([JSON.stringify(data)], {
const file = new File([JSON.stringify(data)], "data.json", {
type: "application/json",
});
blob.name = "data.json";

const promise = session.createComponent(blob);
const promise = session.createComponent(file);
promise
.then((response) => {
response[0].data.__entity_type__.should.equal("FileComponent");
Expand All @@ -313,19 +312,31 @@ describe("Session", () => {
.then(done);
});

it.skip("Should support abort of uploading file", (done) => {
it("Should support uploading blob", () => {
const data = { foo: "bar" };
const blob = new Blob([JSON.stringify(data)], {
type: "application/json",
});
blob.name = "data.json";

return session.createComponent(blob, {
name: "data.json",
});
});

it("Should support abort of uploading file", (done) => {
const data = { foo: "bar" };
const blob = new Blob([JSON.stringify(data)], {
type: "application/json",
});

const xhr = new XMLHttpRequest();
const onAborted = () => {
done();
};

session.createComponent(blob, {
xhr,
name: "data.json",
onProgress: () => {
xhr.abort();
},
Expand Down Expand Up @@ -457,22 +468,19 @@ describe("Session", () => {
.then(done);
});

it.skip("Should support uploading files with custom component id", (done) => {
it("Should support uploading files with custom component id", async () => {
const componentId = uuidV4();
const data = { foo: "bar" };
const blob = new Blob([JSON.stringify(data)], {
type: "application/json",
});
blob.name = "data.json";

const promise = session.createComponent(blob, {
const response = await session.createComponent(blob, {
name: "data.json",
data: { id: componentId },
});
promise
.then((response) => {
response[0].data.id.should.equal(componentId);
})
.then(done);

response[0].data.id.should.equal(componentId);
});

it("Should support generating thumbnail URL with + in username", () => {
Expand Down