Skip to content

Commit

Permalink
[BREAKING] serveResources middleware: Expect *.properties files in UT…
Browse files Browse the repository at this point in the history
…F-8 by default

Also fix some tests that expected different unicode escape sequences
for the same input. The used input encoding did not match the specified
propertiesFileSourceEncoding.

BREAKING CHANGE:
If the project a "*.properties" resource originates from cannot be
determined, or if the project does not define a
propertiesFileSourceEncoding configuration or uses a legacy specVersion
(<2.0), the serveResources middleware assumes that the resource is UTF-8
encoded instead of ISO-8859-1.
  • Loading branch information
RandomByte committed Mar 30, 2020
1 parent 80b2385 commit af7f9ad
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 8 deletions.
14 changes: 12 additions & 2 deletions lib/middleware/serveResources.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,19 @@ function createMiddleware({resources, middlewareUtil}) {
// Special handling for *.properties files escape non ascii characters.
const nonAsciiEscaper = require("@ui5/builder").processors.nonAsciiEscaper;
const project = resource._project; // _project might not be defined
const propertiesFileSourceEncoding = project && project.resources &&
let propertiesFileSourceEncoding = project && project.resources &&
project.resources.configuration && project.resources.configuration.propertiesFileSourceEncoding;
const encoding = nonAsciiEscaper.getEncodingFromAlias(propertiesFileSourceEncoding || "ISO-8859-1");

if (!propertiesFileSourceEncoding) {
if (project && ["0.1", "1.0", "1.1"].includes(project.specVersion)) {
// default encoding to "ISO-8859-1" for old specVersions
propertiesFileSourceEncoding = "ISO-8859-1";
} else {
// default encoding to "UTF-8" for all projects starting with specVersion 2.0
propertiesFileSourceEncoding = "UTF-8";
}
}
const encoding = nonAsciiEscaper.getEncodingFromAlias(propertiesFileSourceEncoding);
await nonAsciiEscaper({
resources: [resource], options: {
encoding
Expand Down
88 changes: 82 additions & 6 deletions test/lib/server/middleware/serveResources.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const {Readable, Writable} = require("stream");
const resourceFactory = require("@ui5/fs").resourceFactory;
const serveResourcesMiddleware = require("../../../../lib/middleware/serveResources");
const MiddlewareUtil = require("../../../../lib/middleware/MiddlewareUtil");
const writeResource = function(writer, path, size, stringContent, project) {
const writeResource = function(writer, path, size, stringContent, stringEncoding, project) {
const statInfo = {
ino: 0,
ctime: new Date(),
Expand All @@ -16,7 +16,7 @@ const writeResource = function(writer, path, size, stringContent, project) {
};
const resource = resourceFactory.createResource({
path,
buffer: Buffer.from(stringContent, "latin1"),
buffer: Buffer.from(stringContent, stringEncoding),
statInfo,
project
});
Expand Down Expand Up @@ -51,7 +51,7 @@ test.serial("Check if properties file is served properly", (t) => {
}
};

return writeResource(readerWriter, "/myFile3.properties", 1024 * 1024, "key=titel\nfame=straße", project)
return writeResource(readerWriter, "/myFile3.properties", 1024 * 1024, "key=titel\nfame=straße", "latin1", project)
.then((resource) => {
const setStringSpy = sinon.spy(resource, "setString");
const middleware = serveResourcesMiddleware({
Expand Down Expand Up @@ -95,7 +95,7 @@ test.serial("Check if properties file is served properly with UTF-8", (t) => {
}
};

return writeResource(readerWriter, "/myFile3.properties", 1024 * 1024, "key=titel\nfame=straße", project)
return writeResource(readerWriter, "/myFile3.properties", 1024 * 1024, "key=titel\nfame=straße", "utf8", project)
.then((resource) => {
const setStringSpy = sinon.spy(resource, "setString");
const middleware = serveResourcesMiddleware({
Expand All @@ -119,7 +119,7 @@ test.serial("Check if properties file is served properly with UTF-8", (t) => {
return resource.getString();
}).then((content) => {
t.is(content, `key=titel
fame=stra\\ufffde`);
fame=stra\\u00dfe`);
t.is(setHeaderSpy.callCount, 2);
t.is(setStringSpy.callCount, 1);
t.is(setHeaderSpy.getCall(0).lastArg, "application/octet-stream");
Expand All @@ -132,7 +132,83 @@ test.serial("Check if properties file is served properly without property settin

const readerWriter = resourceFactory.createAdapter({virBasePath: "/"});

return writeResource(readerWriter, "/myFile3.properties", 1024 * 1024, "key=titel\nfame=straße").then((resource) => {
return writeResource(readerWriter, "/myFile3.properties", 1024 * 1024, "key=titel\nfame=straße", "utf8").then((resource) => {
const setStringSpy = sinon.spy(resource, "setString");
const middleware = serveResourcesMiddleware({
middlewareUtil: new MiddlewareUtil(),
resources: {
all: readerWriter
}
});

const response = fakeResponse;

const setHeaderSpy = sinon.spy(response, "setHeader");
const req = {
url: "/myFile3.properties",
headers: {}
};
const next = function(err) {
throw new Error(`Next callback called with error: ${err.stack}`);
};
return middleware(req, response, next).then((o) => {
return resource.getString();
}).then((content) => {
t.is(content, `key=titel
fame=stra\\u00dfe`);
t.is(setHeaderSpy.callCount, 2);
t.is(setStringSpy.callCount, 1);
t.is(setHeaderSpy.getCall(0).lastArg, "application/octet-stream");
});
});
});

test.serial("Check if properties file is served properly without property setting but legacy spec version", (t) => {
t.plan(4);

const readerWriter = resourceFactory.createAdapter({virBasePath: "/"});
const project = {
specVersion: "1.1"
};
return writeResource(readerWriter, "/myFile3.properties", 1024 * 1024, "key=titel\nfame=straße", "latin1", project).then((resource) => {
const setStringSpy = sinon.spy(resource, "setString");
const middleware = serveResourcesMiddleware({
middlewareUtil: new MiddlewareUtil(),
resources: {
all: readerWriter
}
});

const response = fakeResponse;

const setHeaderSpy = sinon.spy(response, "setHeader");
const req = {
url: "/myFile3.properties",
headers: {}
};
const next = function(err) {
throw new Error(`Next callback called with error: ${err.stack}`);
};
return middleware(req, response, next).then((o) => {
return resource.getString();
}).then((content) => {
t.is(content, `key=titel
fame=stra\\u00dfe`);
t.is(setHeaderSpy.callCount, 2);
t.is(setStringSpy.callCount, 1);
t.is(setHeaderSpy.getCall(0).lastArg, "application/octet-stream");
});
});
});

test.serial("Check if properties file is served properly without property setting but spec version", (t) => {
t.plan(4);

const readerWriter = resourceFactory.createAdapter({virBasePath: "/"});
const project = {
specVersion: "2.0"
};
return writeResource(readerWriter, "/myFile3.properties", 1024 * 1024, "key=titel\nfame=straße", "utf8", project).then((resource) => {
const setStringSpy = sinon.spy(resource, "setString");
const middleware = serveResourcesMiddleware({
middlewareUtil: new MiddlewareUtil(),
Expand Down

0 comments on commit af7f9ad

Please sign in to comment.