@dhis2/app-service-data 3.4.3 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/links/RestAPILink/queryToRequestOptions/multipartFormDataMatchers.js +3 -10
- package/build/cjs/links/RestAPILink/queryToRequestOptions/multipartFormDataMatchers.test.js +12 -29
- package/build/cjs/links/RestAPILink/queryToRequestOptions/requestContentType.js +19 -10
- package/build/cjs/links/RestAPILink/queryToRequestOptions/requestContentType.test.js +34 -13
- package/build/cjs/links/RestAPILink/queryToRequestOptions/textPlainMatchers.test.js +29 -29
- package/build/cjs/links/RestAPILink/queryToRequestOptions/xWwwFormUrlencodedMatchers.js +13 -0
- package/build/cjs/links/RestAPILink/queryToRequestOptions/xWwwFormUrlencodedMatchers.test.js +21 -0
- package/build/cjs/react/components/DataProvider.js +1 -0
- package/build/es/links/RestAPILink/queryToRequestOptions/multipartFormDataMatchers.js +1 -5
- package/build/es/links/RestAPILink/queryToRequestOptions/multipartFormDataMatchers.test.js +13 -30
- package/build/es/links/RestAPILink/queryToRequestOptions/requestContentType.js +17 -8
- package/build/es/links/RestAPILink/queryToRequestOptions/requestContentType.test.js +35 -14
- package/build/es/links/RestAPILink/queryToRequestOptions/textPlainMatchers.test.js +29 -29
- package/build/es/links/RestAPILink/queryToRequestOptions/xWwwFormUrlencodedMatchers.js +4 -0
- package/build/es/links/RestAPILink/queryToRequestOptions/xWwwFormUrlencodedMatchers.test.js +18 -0
- package/build/es/react/components/DataProvider.js +1 -0
- package/build/types/links/RestAPILink/queryToRequestOptions/multipartFormDataMatchers.d.ts +0 -1
- package/build/types/links/RestAPILink/queryToRequestOptions/requestContentType.d.ts +2 -3
- package/build/types/links/RestAPILink/queryToRequestOptions/xWwwFormUrlencodedMatchers.d.ts +2 -0
- package/package.json +2 -2
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.isAppInstall = exports.isStaticContentUpload = exports.isMessageConversationAttachment = exports.isFileResourceUpload = exports.isDataValue = void 0;
|
|
7
7
|
|
|
8
8
|
/*
|
|
9
9
|
* Requests that expect a "multipart/form-data" Content-Type have been collected by scanning
|
|
@@ -45,13 +45,6 @@ exports.isStaticContentUpload = isStaticContentUpload;
|
|
|
45
45
|
|
|
46
46
|
const isAppInstall = (type, {
|
|
47
47
|
resource
|
|
48
|
-
}) => type === 'create' && resource === 'apps';
|
|
48
|
+
}) => type === 'create' && resource === 'apps';
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
exports.isAppInstall = isAppInstall;
|
|
52
|
-
|
|
53
|
-
const isSvgConversion = (type, {
|
|
54
|
-
resource
|
|
55
|
-
}) => type === 'create' && (resource === 'svg.png' || resource === 'svg.pdf');
|
|
56
|
-
|
|
57
|
-
exports.isSvgConversion = isSvgConversion;
|
|
50
|
+
exports.isAppInstall = isAppInstall;
|
|
@@ -6,86 +6,69 @@ describe('isDataValue', () => {
|
|
|
6
6
|
it('returns true for a POST to "dataValues"', () => {
|
|
7
7
|
expect((0, _multipartFormDataMatchers.isDataValue)('create', {
|
|
8
8
|
resource: 'dataValues'
|
|
9
|
-
})).
|
|
9
|
+
})).toBe(true);
|
|
10
10
|
});
|
|
11
11
|
it('returns true for a POST to "dataValues/file"', () => {
|
|
12
12
|
expect((0, _multipartFormDataMatchers.isDataValue)('create', {
|
|
13
13
|
resource: 'dataValues/file'
|
|
14
|
-
})).
|
|
14
|
+
})).toBe(true);
|
|
15
15
|
});
|
|
16
16
|
it('returns false for a POST to a different resource', () => {
|
|
17
17
|
expect((0, _multipartFormDataMatchers.isDataValue)('create', {
|
|
18
18
|
resource: 'somethingElse'
|
|
19
|
-
})).
|
|
19
|
+
})).toBe(false);
|
|
20
20
|
});
|
|
21
21
|
});
|
|
22
22
|
describe('isFileResourceUpload', () => {
|
|
23
23
|
it('returns true for a POST to "fileResources"', () => {
|
|
24
24
|
expect((0, _multipartFormDataMatchers.isFileResourceUpload)('create', {
|
|
25
25
|
resource: 'fileResources'
|
|
26
|
-
})).
|
|
26
|
+
})).toBe(true);
|
|
27
27
|
});
|
|
28
28
|
it('retuns false for a POST to a different resource', () => {
|
|
29
29
|
expect((0, _multipartFormDataMatchers.isFileResourceUpload)('create', {
|
|
30
30
|
resource: 'notFileResources'
|
|
31
|
-
})).
|
|
31
|
+
})).toBe(false);
|
|
32
32
|
});
|
|
33
33
|
});
|
|
34
34
|
describe('isMessageConversationAttachment', () => {
|
|
35
35
|
it('returns true for a POST to "messageConversations/attachments"', () => {
|
|
36
36
|
expect((0, _multipartFormDataMatchers.isMessageConversationAttachment)('create', {
|
|
37
37
|
resource: 'messageConversations/attachments'
|
|
38
|
-
})).
|
|
38
|
+
})).toBe(true);
|
|
39
39
|
});
|
|
40
40
|
it('retuns false for a POST to a different resource', () => {
|
|
41
41
|
expect((0, _multipartFormDataMatchers.isMessageConversationAttachment)('create', {
|
|
42
42
|
resource: 'messageConversations/notAttachments'
|
|
43
|
-
})).
|
|
43
|
+
})).toBe(false);
|
|
44
44
|
});
|
|
45
45
|
});
|
|
46
46
|
describe('isStaticContentUpload', () => {
|
|
47
47
|
it('returns true for a POST to "staticContent/logo_banner"', () => {
|
|
48
48
|
expect((0, _multipartFormDataMatchers.isStaticContentUpload)('create', {
|
|
49
49
|
resource: 'staticContent/logo_banner'
|
|
50
|
-
})).
|
|
50
|
+
})).toBe(true);
|
|
51
51
|
});
|
|
52
52
|
it('returns true for a POST to "staticContent/logo_front"', () => {
|
|
53
53
|
expect((0, _multipartFormDataMatchers.isStaticContentUpload)('create', {
|
|
54
54
|
resource: 'staticContent/logo_front'
|
|
55
|
-
})).
|
|
55
|
+
})).toBe(true);
|
|
56
56
|
});
|
|
57
57
|
it('returns false for a request to a different resource', () => {
|
|
58
58
|
expect((0, _multipartFormDataMatchers.isStaticContentUpload)('create', {
|
|
59
59
|
resource: 'staticContent/no_logo'
|
|
60
|
-
})).
|
|
60
|
+
})).toBe(false);
|
|
61
61
|
});
|
|
62
62
|
});
|
|
63
63
|
describe('isAppInstall', () => {
|
|
64
64
|
it('returns true for a POST to "apps"', () => {
|
|
65
65
|
expect((0, _multipartFormDataMatchers.isAppInstall)('create', {
|
|
66
66
|
resource: 'apps'
|
|
67
|
-
})).
|
|
67
|
+
})).toBe(true);
|
|
68
68
|
});
|
|
69
69
|
it('retuns false for a POST to a different resource', () => {
|
|
70
70
|
expect((0, _multipartFormDataMatchers.isAppInstall)('create', {
|
|
71
71
|
resource: 'notApps'
|
|
72
|
-
})).
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
describe('isSvgConversion', () => {
|
|
76
|
-
it('returns true for a POST to "svg.png"', () => {
|
|
77
|
-
expect((0, _multipartFormDataMatchers.isSvgConversion)('create', {
|
|
78
|
-
resource: 'svg.png'
|
|
79
|
-
})).toEqual(true);
|
|
80
|
-
});
|
|
81
|
-
it('returns true for a POST to "svg.pdf"', () => {
|
|
82
|
-
expect((0, _multipartFormDataMatchers.isSvgConversion)('create', {
|
|
83
|
-
resource: 'svg.pdf'
|
|
84
|
-
})).toEqual(true);
|
|
85
|
-
});
|
|
86
|
-
it('retuns false for a POST to a different resource', () => {
|
|
87
|
-
expect((0, _multipartFormDataMatchers.isSvgConversion)('create', {
|
|
88
|
-
resource: 'notSvg'
|
|
89
|
-
})).toEqual(false);
|
|
72
|
+
})).toBe(false);
|
|
90
73
|
});
|
|
91
74
|
});
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.requestBodyForContentType = exports.requestHeadersForContentType = exports.requestContentType =
|
|
6
|
+
exports.requestBodyForContentType = exports.requestHeadersForContentType = exports.requestContentType = void 0;
|
|
7
7
|
|
|
8
8
|
var multipartFormDataMatchers = _interopRequireWildcard(require("./multipartFormDataMatchers"));
|
|
9
9
|
|
|
10
10
|
var textPlainMatchers = _interopRequireWildcard(require("./textPlainMatchers"));
|
|
11
11
|
|
|
12
|
+
var xWwwFormUrlencodedMatchers = _interopRequireWildcard(require("./xWwwFormUrlencodedMatchers"));
|
|
13
|
+
|
|
12
14
|
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
|
13
15
|
|
|
14
16
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
@@ -17,20 +19,19 @@ const resourceExpectsTextPlain = (type, query) => Object.values(textPlainMatcher
|
|
|
17
19
|
|
|
18
20
|
const resourceExpectsMultipartFormData = (type, query) => Object.values(multipartFormDataMatchers).some(multipartFormDataMatcher => multipartFormDataMatcher(type, query));
|
|
19
21
|
|
|
20
|
-
const
|
|
21
|
-
exports.FORM_DATA_ERROR_MSG = FORM_DATA_ERROR_MSG;
|
|
22
|
+
const resourceExpectsXWwwFormUrlencoded = (type, query) => Object.values(xWwwFormUrlencodedMatchers).some(xWwwFormUrlencodedMatcher => xWwwFormUrlencodedMatcher(type, query));
|
|
22
23
|
|
|
23
|
-
const
|
|
24
|
+
const convertData = (data, initialValue) => {
|
|
24
25
|
const dataEntries = Object.entries(data);
|
|
25
26
|
|
|
26
27
|
if (dataEntries.length === 0) {
|
|
27
|
-
throw new Error(
|
|
28
|
+
throw new Error("Could not convert data to ".concat(initialValue.constructor.name, ": object does not have own enumerable string-keyed properties"));
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
return dataEntries.reduce((
|
|
31
|
-
|
|
32
|
-
return
|
|
33
|
-
},
|
|
31
|
+
return dataEntries.reduce((convertedData, [key, value]) => {
|
|
32
|
+
convertedData.append(key, value);
|
|
33
|
+
return convertedData;
|
|
34
|
+
}, initialValue);
|
|
34
35
|
};
|
|
35
36
|
|
|
36
37
|
const requestContentType = (type, query) => {
|
|
@@ -50,6 +51,10 @@ const requestContentType = (type, query) => {
|
|
|
50
51
|
return 'multipart/form-data';
|
|
51
52
|
}
|
|
52
53
|
|
|
54
|
+
if (resourceExpectsXWwwFormUrlencoded(type, query)) {
|
|
55
|
+
return 'application/x-www-form-urlencoded';
|
|
56
|
+
}
|
|
57
|
+
|
|
53
58
|
return 'application/json';
|
|
54
59
|
};
|
|
55
60
|
|
|
@@ -86,7 +91,11 @@ const requestBodyForContentType = (contentType, {
|
|
|
86
91
|
}
|
|
87
92
|
|
|
88
93
|
if (contentType === 'multipart/form-data') {
|
|
89
|
-
return
|
|
94
|
+
return convertData(data, new FormData());
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (contentType === 'application/x-www-form-urlencoded') {
|
|
98
|
+
return convertData(data, new URLSearchParams());
|
|
90
99
|
} // 'text/plain'
|
|
91
100
|
|
|
92
101
|
|
|
@@ -7,33 +7,33 @@ describe('requestContentType', () => {
|
|
|
7
7
|
expect((0, _requestContentType.requestContentType)('create', {
|
|
8
8
|
resource: 'test',
|
|
9
9
|
data: 'test'
|
|
10
|
-
})).
|
|
10
|
+
})).toBe('application/json');
|
|
11
11
|
});
|
|
12
12
|
it('returns "application/json-patch+json" when the fetch type is "json-patch"', () => {
|
|
13
13
|
expect((0, _requestContentType.requestContentType)('json-patch', {
|
|
14
14
|
resource: 'test',
|
|
15
15
|
data: 'test'
|
|
16
|
-
})).
|
|
16
|
+
})).toBe('application/json-patch+json');
|
|
17
17
|
});
|
|
18
18
|
it('returns "multipart/form-data" for a specific resource that expects it', () => {
|
|
19
19
|
expect((0, _requestContentType.requestContentType)('create', {
|
|
20
20
|
resource: 'fileResources',
|
|
21
21
|
data: 'test'
|
|
22
|
-
})).
|
|
22
|
+
})).toBe('multipart/form-data');
|
|
23
23
|
});
|
|
24
24
|
it('returns "text/plain" for a specific resource that expects it', () => {
|
|
25
25
|
expect((0, _requestContentType.requestContentType)('create', {
|
|
26
26
|
resource: 'messageConversations/feedback',
|
|
27
27
|
data: 'test'
|
|
28
|
-
})).
|
|
28
|
+
})).toBe('text/plain');
|
|
29
29
|
});
|
|
30
30
|
});
|
|
31
31
|
describe('requestHeadersForContentType', () => {
|
|
32
32
|
it('returns undefined if contentType is null', () => {
|
|
33
|
-
expect((0, _requestContentType.requestHeadersForContentType)(null)).
|
|
33
|
+
expect((0, _requestContentType.requestHeadersForContentType)(null)).toBe(undefined);
|
|
34
34
|
});
|
|
35
35
|
it('returns undefined if contentType is "multipart/form-data"', () => {
|
|
36
|
-
expect((0, _requestContentType.requestHeadersForContentType)('multipart/form-data')).
|
|
36
|
+
expect((0, _requestContentType.requestHeadersForContentType)('multipart/form-data')).toBe(undefined);
|
|
37
37
|
});
|
|
38
38
|
it('returns a headers object with the contentType for "application/json"', () => {
|
|
39
39
|
expect((0, _requestContentType.requestHeadersForContentType)('application/json')).toEqual({
|
|
@@ -50,7 +50,7 @@ describe('requestBodyForContentType', () => {
|
|
|
50
50
|
it('returns undefined if data is undefined', () => {
|
|
51
51
|
expect((0, _requestContentType.requestBodyForContentType)('application/json', {
|
|
52
52
|
resource: 'test'
|
|
53
|
-
})).
|
|
53
|
+
})).toBe(undefined);
|
|
54
54
|
});
|
|
55
55
|
it('JSON stringifies the data if contentType is "application/json"', () => {
|
|
56
56
|
const dataIn = {
|
|
@@ -62,7 +62,7 @@ describe('requestBodyForContentType', () => {
|
|
|
62
62
|
expect((0, _requestContentType.requestBodyForContentType)('application/json', {
|
|
63
63
|
resource: 'test',
|
|
64
64
|
data: dataIn
|
|
65
|
-
})).
|
|
65
|
+
})).toBe(dataOut);
|
|
66
66
|
});
|
|
67
67
|
it('converts to FormData if contentType is "multipart/form-data"', () => {
|
|
68
68
|
const file = new File(['foo'], 'foo.txt', {
|
|
@@ -76,9 +76,9 @@ describe('requestBodyForContentType', () => {
|
|
|
76
76
|
resource: 'test',
|
|
77
77
|
data
|
|
78
78
|
});
|
|
79
|
-
expect(result instanceof FormData).
|
|
80
|
-
expect(result.get('a')).
|
|
81
|
-
expect(result.get('file')).
|
|
79
|
+
expect(result instanceof FormData).toBe(true);
|
|
80
|
+
expect(result.get('a')).toBe('AAA');
|
|
81
|
+
expect(result.get('file')).toBe(file);
|
|
82
82
|
});
|
|
83
83
|
it('throws an error if contentType is "multipart/form-data" and data does have own string-keyd properties', () => {
|
|
84
84
|
expect(() => {
|
|
@@ -88,13 +88,34 @@ describe('requestBodyForContentType', () => {
|
|
|
88
88
|
type: 'text/plain'
|
|
89
89
|
})
|
|
90
90
|
});
|
|
91
|
-
}).
|
|
91
|
+
}).toThrowErrorMatchingInlineSnapshot("\"Could not convert data to FormData: object does not have own enumerable string-keyed properties\"");
|
|
92
|
+
});
|
|
93
|
+
it('converts to URLSearchParams if contentType is "application/x-www-form-urlencoded"', () => {
|
|
94
|
+
const data = {
|
|
95
|
+
a: 'AAA'
|
|
96
|
+
};
|
|
97
|
+
const result = (0, _requestContentType.requestBodyForContentType)('application/x-www-form-urlencoded', {
|
|
98
|
+
resource: 'test',
|
|
99
|
+
data
|
|
100
|
+
});
|
|
101
|
+
expect(result instanceof URLSearchParams).toBe(true);
|
|
102
|
+
expect(result.get('a')).toBe('AAA');
|
|
103
|
+
});
|
|
104
|
+
it('throws an error if contentType is "application/x-www-form-urlencoded" and data does have own string-keyd properties', () => {
|
|
105
|
+
expect(() => {
|
|
106
|
+
(0, _requestContentType.requestBodyForContentType)('application/x-www-form-urlencoded', {
|
|
107
|
+
resource: 'test',
|
|
108
|
+
data: new File(['foo'], 'foo.txt', {
|
|
109
|
+
type: 'text/plain'
|
|
110
|
+
})
|
|
111
|
+
});
|
|
112
|
+
}).toThrowErrorMatchingInlineSnapshot("\"Could not convert data to URLSearchParams: object does not have own enumerable string-keyed properties\"");
|
|
92
113
|
});
|
|
93
114
|
it('returns the data as received if contentType is "text/plain"', () => {
|
|
94
115
|
const data = 'Something';
|
|
95
116
|
expect((0, _requestContentType.requestBodyForContentType)('text/plain', {
|
|
96
117
|
resource: 'messageConversations/feedback',
|
|
97
118
|
data
|
|
98
|
-
})).
|
|
119
|
+
})).toBe(data);
|
|
99
120
|
});
|
|
100
121
|
});
|
|
@@ -6,164 +6,164 @@ describe('isReplyToMessageConversation', () => {
|
|
|
6
6
|
it('retuns true for POST to `messageConversations/${id}`', () => {
|
|
7
7
|
expect((0, _textPlainMatchers.isReplyToMessageConversation)('create', {
|
|
8
8
|
resource: 'messageConversations/oXD88WWSQpR'
|
|
9
|
-
})).
|
|
9
|
+
})).toBe(true);
|
|
10
10
|
});
|
|
11
11
|
it('retuns false for a POST to a different resource', () => {
|
|
12
12
|
expect((0, _textPlainMatchers.isReplyToMessageConversation)('create', {
|
|
13
13
|
resource: 'test/oXD88WWSQpR'
|
|
14
|
-
})).
|
|
14
|
+
})).toBe(false);
|
|
15
15
|
});
|
|
16
16
|
});
|
|
17
17
|
describe('isCreateFeedbackMessage', () => {
|
|
18
18
|
it('returns true for a POST to "messageConversations/feedback"', () => {
|
|
19
19
|
expect((0, _textPlainMatchers.isCreateFeedbackMessage)('create', {
|
|
20
20
|
resource: 'messageConversations/feedback'
|
|
21
|
-
})).
|
|
21
|
+
})).toBe(true);
|
|
22
22
|
});
|
|
23
23
|
it('retuns false for a POST to a different resource', () => {
|
|
24
24
|
expect((0, _textPlainMatchers.isCreateFeedbackMessage)('create', {
|
|
25
25
|
resource: 'messageConversations/somethingelse'
|
|
26
|
-
})).
|
|
26
|
+
})).toBe(false);
|
|
27
27
|
});
|
|
28
28
|
});
|
|
29
29
|
describe('isCreateInterpretation', () => {
|
|
30
30
|
it('returns true for a POST to "interpretations/chart/${id}"', () => {
|
|
31
31
|
expect((0, _textPlainMatchers.isCreateInterpretation)('create', {
|
|
32
32
|
resource: 'interpretations/chart/oXD88WWSQpR'
|
|
33
|
-
})).
|
|
33
|
+
})).toBe(true);
|
|
34
34
|
});
|
|
35
35
|
it('returns false for a PUT to "interpretations/chart/${id}"', () => {
|
|
36
36
|
expect((0, _textPlainMatchers.isCreateInterpretation)('replace', {
|
|
37
37
|
resource: 'interpretations/chart/oXD88WWSQpR'
|
|
38
|
-
})).
|
|
38
|
+
})).toBe(false);
|
|
39
39
|
});
|
|
40
40
|
it('retuns false for PATCH requests with a valid query', () => {
|
|
41
41
|
expect((0, _textPlainMatchers.isCreateInterpretation)('update', {
|
|
42
42
|
resource: 'interpretations/chart/oXD88WWSQpR'
|
|
43
|
-
})).
|
|
43
|
+
})).toBe(false);
|
|
44
44
|
});
|
|
45
45
|
it('returns false for a request to a different resource', () => {
|
|
46
46
|
expect((0, _textPlainMatchers.isCreateInterpretation)('create', {
|
|
47
47
|
resource: 'interpretations/dummy/oXD88WWSQpR'
|
|
48
|
-
})).
|
|
48
|
+
})).toBe(false);
|
|
49
49
|
});
|
|
50
50
|
});
|
|
51
51
|
describe('isUpdateInterpretation', () => {
|
|
52
52
|
it('returns true for a PUT to "interpretations/${id}"', () => {
|
|
53
53
|
expect((0, _textPlainMatchers.isUpdateInterpretation)('replace', {
|
|
54
54
|
resource: 'interpretations/oXD88WWSQpR'
|
|
55
|
-
})).
|
|
55
|
+
})).toBe(true);
|
|
56
56
|
});
|
|
57
57
|
it('returns true for PUT with populated query.id', () => {
|
|
58
58
|
expect((0, _textPlainMatchers.isUpdateInterpretation)('replace', {
|
|
59
59
|
resource: 'interpretations',
|
|
60
60
|
id: 'oXD88WWSQpR'
|
|
61
|
-
})).
|
|
61
|
+
})).toBe(true);
|
|
62
62
|
});
|
|
63
63
|
it('returns false for a POST to "interpretations/${id}"', () => {
|
|
64
64
|
expect((0, _textPlainMatchers.isUpdateInterpretation)('create', {
|
|
65
65
|
resource: 'interpretations/oXD88WWSQpR'
|
|
66
|
-
})).
|
|
66
|
+
})).toBe(false);
|
|
67
67
|
});
|
|
68
68
|
it('returns false for a PATCH to "interpretations/${id}"', () => {
|
|
69
69
|
expect((0, _textPlainMatchers.isUpdateInterpretation)('update', {
|
|
70
70
|
resource: 'interpretations/oXD88WWSQpR'
|
|
71
|
-
})).
|
|
71
|
+
})).toBe(false);
|
|
72
72
|
});
|
|
73
73
|
it('returns false for PATCH with populated query.id', () => {
|
|
74
74
|
expect((0, _textPlainMatchers.isUpdateInterpretation)('update', {
|
|
75
75
|
resource: 'interpretations',
|
|
76
76
|
id: 'oXD88WWSQpR'
|
|
77
|
-
})).
|
|
77
|
+
})).toBe(false);
|
|
78
78
|
});
|
|
79
79
|
it('returns false for a request to a different resource', () => {
|
|
80
80
|
expect((0, _textPlainMatchers.isUpdateInterpretation)('create', {
|
|
81
81
|
resource: 'interpretations/dummy/oXD88WWSQpR'
|
|
82
|
-
})).
|
|
82
|
+
})).toBe(false);
|
|
83
83
|
});
|
|
84
84
|
});
|
|
85
85
|
describe('isCommentOnInterpretation', () => {
|
|
86
86
|
it('retuns true for POST to `interpretations/${id}/comments`', () => {
|
|
87
87
|
expect((0, _textPlainMatchers.isCommentOnInterpretation)('create', {
|
|
88
88
|
resource: 'interpretations/oXD88WWSQpR/comments'
|
|
89
|
-
})).
|
|
89
|
+
})).toBe(true);
|
|
90
90
|
});
|
|
91
91
|
it('retuns false for a POST to a different resource', () => {
|
|
92
92
|
expect((0, _textPlainMatchers.isCommentOnInterpretation)('create', {
|
|
93
93
|
resource: 'test/oXD88WWSQpR/comments'
|
|
94
|
-
})).
|
|
94
|
+
})).toBe(false);
|
|
95
95
|
});
|
|
96
96
|
});
|
|
97
97
|
describe('isInterpretationCommentUpdate', () => {
|
|
98
98
|
it('returns true for a PUT to `interpretations/${interpretationId}/comments/${commentId}`', () => {
|
|
99
99
|
expect((0, _textPlainMatchers.isInterpretationCommentUpdate)('replace', {
|
|
100
100
|
resource: 'interpretations/oXD88WWSQpR/comments/oXD88WWSQpR'
|
|
101
|
-
})).
|
|
101
|
+
})).toBe(true);
|
|
102
102
|
});
|
|
103
103
|
it('returns true for PUT with populated query.id', () => {
|
|
104
104
|
expect((0, _textPlainMatchers.isInterpretationCommentUpdate)('replace', {
|
|
105
105
|
resource: 'interpretations',
|
|
106
106
|
id: 'oXD88WWSQpR/comments/oXD88WWSQpR'
|
|
107
|
-
})).
|
|
107
|
+
})).toBe(true);
|
|
108
108
|
expect((0, _textPlainMatchers.isInterpretationCommentUpdate)('replace', {
|
|
109
109
|
resource: 'interpretations/oXD88WWSQpR/comments',
|
|
110
110
|
id: 'oXD88WWSQpR'
|
|
111
|
-
})).
|
|
111
|
+
})).toBe(true);
|
|
112
112
|
});
|
|
113
113
|
it('retuns false for PATCH requests with a valid query', () => {
|
|
114
114
|
expect((0, _textPlainMatchers.isInterpretationCommentUpdate)('update', {
|
|
115
115
|
resource: 'interpretations/oXD88WWSQpR/comments/oXD88WWSQpR'
|
|
116
|
-
})).
|
|
116
|
+
})).toBe(false);
|
|
117
117
|
});
|
|
118
118
|
it('returns false for a request to a different resource', () => {
|
|
119
119
|
expect((0, _textPlainMatchers.isInterpretationCommentUpdate)('create', {
|
|
120
120
|
resource: 'interpretations/oXD88WWSQpR/dummy/oXD88WWSQpR'
|
|
121
|
-
})).
|
|
121
|
+
})).toBe(false);
|
|
122
122
|
});
|
|
123
123
|
});
|
|
124
124
|
describe('isAddOrUpdateSystemOrUserSetting', () => {
|
|
125
125
|
it('retuns true for POST to `systemSettings/${settingKey}`', () => {
|
|
126
126
|
expect((0, _textPlainMatchers.isAddOrUpdateSystemOrUserSetting)('create', {
|
|
127
127
|
resource: 'systemSettings/keyWhatever'
|
|
128
|
-
})).
|
|
128
|
+
})).toBe(true);
|
|
129
129
|
});
|
|
130
130
|
it('retuns true for POST to `userSettings/${settingKey}`', () => {
|
|
131
131
|
expect((0, _textPlainMatchers.isAddOrUpdateSystemOrUserSetting)('create', {
|
|
132
132
|
resource: 'userSettings/keyWhatever'
|
|
133
|
-
})).
|
|
133
|
+
})).toBe(true);
|
|
134
134
|
});
|
|
135
135
|
it('retuns false for a POST to a different resource', () => {
|
|
136
136
|
expect((0, _textPlainMatchers.isAddOrUpdateSystemOrUserSetting)('create', {
|
|
137
137
|
resource: 'test/keyWhatever'
|
|
138
|
-
})).
|
|
138
|
+
})).toBe(false);
|
|
139
139
|
});
|
|
140
140
|
});
|
|
141
141
|
describe('addOrUpdateConfigurationProperty', () => {
|
|
142
142
|
it('retuns true for POST to `configuration/${property}`', () => {
|
|
143
143
|
expect((0, _textPlainMatchers.addOrUpdateConfigurationProperty)('create', {
|
|
144
144
|
resource: 'configuration/whatever'
|
|
145
|
-
})).
|
|
145
|
+
})).toBe(true);
|
|
146
146
|
});
|
|
147
147
|
it('retuns false for POST to `configuration/corsWhitelist`, which needs "application/json"', () => {
|
|
148
148
|
expect((0, _textPlainMatchers.addOrUpdateConfigurationProperty)('create', {
|
|
149
149
|
resource: 'configuration/corsWhitelist'
|
|
150
|
-
})).
|
|
150
|
+
})).toBe(false);
|
|
151
151
|
});
|
|
152
152
|
it('retuns false for a POST to a different resource', () => {
|
|
153
153
|
expect((0, _textPlainMatchers.addOrUpdateConfigurationProperty)('create', {
|
|
154
154
|
resource: 'test/whatever'
|
|
155
|
-
})).
|
|
155
|
+
})).toBe(false);
|
|
156
156
|
});
|
|
157
157
|
});
|
|
158
158
|
describe('isMetadataPackageInstallation', () => {
|
|
159
159
|
it('returns true for a POST to "synchronization/metadataPull"', () => {
|
|
160
160
|
expect((0, _textPlainMatchers.isMetadataPackageInstallation)('create', {
|
|
161
161
|
resource: 'synchronization/metadataPull'
|
|
162
|
-
})).
|
|
162
|
+
})).toBe(true);
|
|
163
163
|
});
|
|
164
164
|
it('retuns false for a POST to a different resource', () => {
|
|
165
165
|
expect((0, _textPlainMatchers.isMetadataPackageInstallation)('create', {
|
|
166
166
|
resource: 'synchronization/somethingelse'
|
|
167
|
-
})).
|
|
167
|
+
})).toBe(false);
|
|
168
168
|
});
|
|
169
169
|
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isSvgConversion = void 0;
|
|
7
|
+
|
|
8
|
+
// POST to convert an SVG file
|
|
9
|
+
const isSvgConversion = (type, {
|
|
10
|
+
resource
|
|
11
|
+
}) => type === 'create' && (resource === 'svg.png' || resource === 'svg.pdf');
|
|
12
|
+
|
|
13
|
+
exports.isSvgConversion = isSvgConversion;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _xWwwFormUrlencodedMatchers = require("./xWwwFormUrlencodedMatchers");
|
|
4
|
+
|
|
5
|
+
describe('isSvgConversion', () => {
|
|
6
|
+
it('returns true for a POST to "svg.png"', () => {
|
|
7
|
+
expect((0, _xWwwFormUrlencodedMatchers.isSvgConversion)('create', {
|
|
8
|
+
resource: 'svg.png'
|
|
9
|
+
})).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
it('returns true for a POST to "svg.pdf"', () => {
|
|
12
|
+
expect((0, _xWwwFormUrlencodedMatchers.isSvgConversion)('create', {
|
|
13
|
+
resource: 'svg.pdf'
|
|
14
|
+
})).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
it('retuns false for a POST to a different resource', () => {
|
|
17
|
+
expect((0, _xWwwFormUrlencodedMatchers.isSvgConversion)('create', {
|
|
18
|
+
resource: 'notSvg'
|
|
19
|
+
})).toBe(false);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -19,6 +19,7 @@ var _DataContext = require("../context/DataContext");
|
|
|
19
19
|
|
|
20
20
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
21
21
|
|
|
22
|
+
/* eslint-disable react/no-unused-prop-types */
|
|
22
23
|
const queryClientOptions = {
|
|
23
24
|
defaultOptions: {
|
|
24
25
|
queries: {
|
|
@@ -26,8 +26,4 @@ export const isStaticContentUpload = (type, {
|
|
|
26
26
|
|
|
27
27
|
export const isAppInstall = (type, {
|
|
28
28
|
resource
|
|
29
|
-
}) => type === 'create' && resource === 'apps';
|
|
30
|
-
|
|
31
|
-
export const isSvgConversion = (type, {
|
|
32
|
-
resource
|
|
33
|
-
}) => type === 'create' && (resource === 'svg.png' || resource === 'svg.pdf');
|
|
29
|
+
}) => type === 'create' && resource === 'apps';
|
|
@@ -1,88 +1,71 @@
|
|
|
1
|
-
import { isFileResourceUpload, isMessageConversationAttachment, isStaticContentUpload, isAppInstall,
|
|
1
|
+
import { isFileResourceUpload, isMessageConversationAttachment, isStaticContentUpload, isAppInstall, isDataValue } from './multipartFormDataMatchers';
|
|
2
2
|
describe('isDataValue', () => {
|
|
3
3
|
it('returns true for a POST to "dataValues"', () => {
|
|
4
4
|
expect(isDataValue('create', {
|
|
5
5
|
resource: 'dataValues'
|
|
6
|
-
})).
|
|
6
|
+
})).toBe(true);
|
|
7
7
|
});
|
|
8
8
|
it('returns true for a POST to "dataValues/file"', () => {
|
|
9
9
|
expect(isDataValue('create', {
|
|
10
10
|
resource: 'dataValues/file'
|
|
11
|
-
})).
|
|
11
|
+
})).toBe(true);
|
|
12
12
|
});
|
|
13
13
|
it('returns false for a POST to a different resource', () => {
|
|
14
14
|
expect(isDataValue('create', {
|
|
15
15
|
resource: 'somethingElse'
|
|
16
|
-
})).
|
|
16
|
+
})).toBe(false);
|
|
17
17
|
});
|
|
18
18
|
});
|
|
19
19
|
describe('isFileResourceUpload', () => {
|
|
20
20
|
it('returns true for a POST to "fileResources"', () => {
|
|
21
21
|
expect(isFileResourceUpload('create', {
|
|
22
22
|
resource: 'fileResources'
|
|
23
|
-
})).
|
|
23
|
+
})).toBe(true);
|
|
24
24
|
});
|
|
25
25
|
it('retuns false for a POST to a different resource', () => {
|
|
26
26
|
expect(isFileResourceUpload('create', {
|
|
27
27
|
resource: 'notFileResources'
|
|
28
|
-
})).
|
|
28
|
+
})).toBe(false);
|
|
29
29
|
});
|
|
30
30
|
});
|
|
31
31
|
describe('isMessageConversationAttachment', () => {
|
|
32
32
|
it('returns true for a POST to "messageConversations/attachments"', () => {
|
|
33
33
|
expect(isMessageConversationAttachment('create', {
|
|
34
34
|
resource: 'messageConversations/attachments'
|
|
35
|
-
})).
|
|
35
|
+
})).toBe(true);
|
|
36
36
|
});
|
|
37
37
|
it('retuns false for a POST to a different resource', () => {
|
|
38
38
|
expect(isMessageConversationAttachment('create', {
|
|
39
39
|
resource: 'messageConversations/notAttachments'
|
|
40
|
-
})).
|
|
40
|
+
})).toBe(false);
|
|
41
41
|
});
|
|
42
42
|
});
|
|
43
43
|
describe('isStaticContentUpload', () => {
|
|
44
44
|
it('returns true for a POST to "staticContent/logo_banner"', () => {
|
|
45
45
|
expect(isStaticContentUpload('create', {
|
|
46
46
|
resource: 'staticContent/logo_banner'
|
|
47
|
-
})).
|
|
47
|
+
})).toBe(true);
|
|
48
48
|
});
|
|
49
49
|
it('returns true for a POST to "staticContent/logo_front"', () => {
|
|
50
50
|
expect(isStaticContentUpload('create', {
|
|
51
51
|
resource: 'staticContent/logo_front'
|
|
52
|
-
})).
|
|
52
|
+
})).toBe(true);
|
|
53
53
|
});
|
|
54
54
|
it('returns false for a request to a different resource', () => {
|
|
55
55
|
expect(isStaticContentUpload('create', {
|
|
56
56
|
resource: 'staticContent/no_logo'
|
|
57
|
-
})).
|
|
57
|
+
})).toBe(false);
|
|
58
58
|
});
|
|
59
59
|
});
|
|
60
60
|
describe('isAppInstall', () => {
|
|
61
61
|
it('returns true for a POST to "apps"', () => {
|
|
62
62
|
expect(isAppInstall('create', {
|
|
63
63
|
resource: 'apps'
|
|
64
|
-
})).
|
|
64
|
+
})).toBe(true);
|
|
65
65
|
});
|
|
66
66
|
it('retuns false for a POST to a different resource', () => {
|
|
67
67
|
expect(isAppInstall('create', {
|
|
68
68
|
resource: 'notApps'
|
|
69
|
-
})).
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
describe('isSvgConversion', () => {
|
|
73
|
-
it('returns true for a POST to "svg.png"', () => {
|
|
74
|
-
expect(isSvgConversion('create', {
|
|
75
|
-
resource: 'svg.png'
|
|
76
|
-
})).toEqual(true);
|
|
77
|
-
});
|
|
78
|
-
it('returns true for a POST to "svg.pdf"', () => {
|
|
79
|
-
expect(isSvgConversion('create', {
|
|
80
|
-
resource: 'svg.pdf'
|
|
81
|
-
})).toEqual(true);
|
|
82
|
-
});
|
|
83
|
-
it('retuns false for a POST to a different resource', () => {
|
|
84
|
-
expect(isSvgConversion('create', {
|
|
85
|
-
resource: 'notSvg'
|
|
86
|
-
})).toEqual(false);
|
|
69
|
+
})).toBe(false);
|
|
87
70
|
});
|
|
88
71
|
});
|
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import * as multipartFormDataMatchers from './multipartFormDataMatchers';
|
|
2
2
|
import * as textPlainMatchers from './textPlainMatchers';
|
|
3
|
+
import * as xWwwFormUrlencodedMatchers from './xWwwFormUrlencodedMatchers';
|
|
3
4
|
|
|
4
5
|
const resourceExpectsTextPlain = (type, query) => Object.values(textPlainMatchers).some(textPlainMatcher => textPlainMatcher(type, query));
|
|
5
6
|
|
|
6
7
|
const resourceExpectsMultipartFormData = (type, query) => Object.values(multipartFormDataMatchers).some(multipartFormDataMatcher => multipartFormDataMatcher(type, query));
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
const resourceExpectsXWwwFormUrlencoded = (type, query) => Object.values(xWwwFormUrlencodedMatchers).some(xWwwFormUrlencodedMatcher => xWwwFormUrlencodedMatcher(type, query));
|
|
9
10
|
|
|
10
|
-
const
|
|
11
|
+
const convertData = (data, initialValue) => {
|
|
11
12
|
const dataEntries = Object.entries(data);
|
|
12
13
|
|
|
13
14
|
if (dataEntries.length === 0) {
|
|
14
|
-
throw new Error(
|
|
15
|
+
throw new Error("Could not convert data to ".concat(initialValue.constructor.name, ": object does not have own enumerable string-keyed properties"));
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
return dataEntries.reduce((
|
|
18
|
-
|
|
19
|
-
return
|
|
20
|
-
},
|
|
18
|
+
return dataEntries.reduce((convertedData, [key, value]) => {
|
|
19
|
+
convertedData.append(key, value);
|
|
20
|
+
return convertedData;
|
|
21
|
+
}, initialValue);
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
export const requestContentType = (type, query) => {
|
|
@@ -37,6 +38,10 @@ export const requestContentType = (type, query) => {
|
|
|
37
38
|
return 'multipart/form-data';
|
|
38
39
|
}
|
|
39
40
|
|
|
41
|
+
if (resourceExpectsXWwwFormUrlencoded(type, query)) {
|
|
42
|
+
return 'application/x-www-form-urlencoded';
|
|
43
|
+
}
|
|
44
|
+
|
|
40
45
|
return 'application/json';
|
|
41
46
|
};
|
|
42
47
|
export const requestHeadersForContentType = contentType => {
|
|
@@ -67,7 +72,11 @@ export const requestBodyForContentType = (contentType, {
|
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
if (contentType === 'multipart/form-data') {
|
|
70
|
-
return
|
|
75
|
+
return convertData(data, new FormData());
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (contentType === 'application/x-www-form-urlencoded') {
|
|
79
|
+
return convertData(data, new URLSearchParams());
|
|
71
80
|
} // 'text/plain'
|
|
72
81
|
|
|
73
82
|
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import { requestContentType, requestHeadersForContentType, requestBodyForContentType
|
|
1
|
+
import { requestContentType, requestHeadersForContentType, requestBodyForContentType } from './requestContentType';
|
|
2
2
|
describe('requestContentType', () => {
|
|
3
3
|
it('returns "application/json" for a normal resource', () => {
|
|
4
4
|
expect(requestContentType('create', {
|
|
5
5
|
resource: 'test',
|
|
6
6
|
data: 'test'
|
|
7
|
-
})).
|
|
7
|
+
})).toBe('application/json');
|
|
8
8
|
});
|
|
9
9
|
it('returns "application/json-patch+json" when the fetch type is "json-patch"', () => {
|
|
10
10
|
expect(requestContentType('json-patch', {
|
|
11
11
|
resource: 'test',
|
|
12
12
|
data: 'test'
|
|
13
|
-
})).
|
|
13
|
+
})).toBe('application/json-patch+json');
|
|
14
14
|
});
|
|
15
15
|
it('returns "multipart/form-data" for a specific resource that expects it', () => {
|
|
16
16
|
expect(requestContentType('create', {
|
|
17
17
|
resource: 'fileResources',
|
|
18
18
|
data: 'test'
|
|
19
|
-
})).
|
|
19
|
+
})).toBe('multipart/form-data');
|
|
20
20
|
});
|
|
21
21
|
it('returns "text/plain" for a specific resource that expects it', () => {
|
|
22
22
|
expect(requestContentType('create', {
|
|
23
23
|
resource: 'messageConversations/feedback',
|
|
24
24
|
data: 'test'
|
|
25
|
-
})).
|
|
25
|
+
})).toBe('text/plain');
|
|
26
26
|
});
|
|
27
27
|
});
|
|
28
28
|
describe('requestHeadersForContentType', () => {
|
|
29
29
|
it('returns undefined if contentType is null', () => {
|
|
30
|
-
expect(requestHeadersForContentType(null)).
|
|
30
|
+
expect(requestHeadersForContentType(null)).toBe(undefined);
|
|
31
31
|
});
|
|
32
32
|
it('returns undefined if contentType is "multipart/form-data"', () => {
|
|
33
|
-
expect(requestHeadersForContentType('multipart/form-data')).
|
|
33
|
+
expect(requestHeadersForContentType('multipart/form-data')).toBe(undefined);
|
|
34
34
|
});
|
|
35
35
|
it('returns a headers object with the contentType for "application/json"', () => {
|
|
36
36
|
expect(requestHeadersForContentType('application/json')).toEqual({
|
|
@@ -47,7 +47,7 @@ describe('requestBodyForContentType', () => {
|
|
|
47
47
|
it('returns undefined if data is undefined', () => {
|
|
48
48
|
expect(requestBodyForContentType('application/json', {
|
|
49
49
|
resource: 'test'
|
|
50
|
-
})).
|
|
50
|
+
})).toBe(undefined);
|
|
51
51
|
});
|
|
52
52
|
it('JSON stringifies the data if contentType is "application/json"', () => {
|
|
53
53
|
const dataIn = {
|
|
@@ -59,7 +59,7 @@ describe('requestBodyForContentType', () => {
|
|
|
59
59
|
expect(requestBodyForContentType('application/json', {
|
|
60
60
|
resource: 'test',
|
|
61
61
|
data: dataIn
|
|
62
|
-
})).
|
|
62
|
+
})).toBe(dataOut);
|
|
63
63
|
});
|
|
64
64
|
it('converts to FormData if contentType is "multipart/form-data"', () => {
|
|
65
65
|
const file = new File(['foo'], 'foo.txt', {
|
|
@@ -73,9 +73,9 @@ describe('requestBodyForContentType', () => {
|
|
|
73
73
|
resource: 'test',
|
|
74
74
|
data
|
|
75
75
|
});
|
|
76
|
-
expect(result instanceof FormData).
|
|
77
|
-
expect(result.get('a')).
|
|
78
|
-
expect(result.get('file')).
|
|
76
|
+
expect(result instanceof FormData).toBe(true);
|
|
77
|
+
expect(result.get('a')).toBe('AAA');
|
|
78
|
+
expect(result.get('file')).toBe(file);
|
|
79
79
|
});
|
|
80
80
|
it('throws an error if contentType is "multipart/form-data" and data does have own string-keyd properties', () => {
|
|
81
81
|
expect(() => {
|
|
@@ -85,13 +85,34 @@ describe('requestBodyForContentType', () => {
|
|
|
85
85
|
type: 'text/plain'
|
|
86
86
|
})
|
|
87
87
|
});
|
|
88
|
-
}).
|
|
88
|
+
}).toThrowErrorMatchingInlineSnapshot("\"Could not convert data to FormData: object does not have own enumerable string-keyed properties\"");
|
|
89
|
+
});
|
|
90
|
+
it('converts to URLSearchParams if contentType is "application/x-www-form-urlencoded"', () => {
|
|
91
|
+
const data = {
|
|
92
|
+
a: 'AAA'
|
|
93
|
+
};
|
|
94
|
+
const result = requestBodyForContentType('application/x-www-form-urlencoded', {
|
|
95
|
+
resource: 'test',
|
|
96
|
+
data
|
|
97
|
+
});
|
|
98
|
+
expect(result instanceof URLSearchParams).toBe(true);
|
|
99
|
+
expect(result.get('a')).toBe('AAA');
|
|
100
|
+
});
|
|
101
|
+
it('throws an error if contentType is "application/x-www-form-urlencoded" and data does have own string-keyd properties', () => {
|
|
102
|
+
expect(() => {
|
|
103
|
+
requestBodyForContentType('application/x-www-form-urlencoded', {
|
|
104
|
+
resource: 'test',
|
|
105
|
+
data: new File(['foo'], 'foo.txt', {
|
|
106
|
+
type: 'text/plain'
|
|
107
|
+
})
|
|
108
|
+
});
|
|
109
|
+
}).toThrowErrorMatchingInlineSnapshot("\"Could not convert data to URLSearchParams: object does not have own enumerable string-keyed properties\"");
|
|
89
110
|
});
|
|
90
111
|
it('returns the data as received if contentType is "text/plain"', () => {
|
|
91
112
|
const data = 'Something';
|
|
92
113
|
expect(requestBodyForContentType('text/plain', {
|
|
93
114
|
resource: 'messageConversations/feedback',
|
|
94
115
|
data
|
|
95
|
-
})).
|
|
116
|
+
})).toBe(data);
|
|
96
117
|
});
|
|
97
118
|
});
|
|
@@ -3,164 +3,164 @@ describe('isReplyToMessageConversation', () => {
|
|
|
3
3
|
it('retuns true for POST to `messageConversations/${id}`', () => {
|
|
4
4
|
expect(isReplyToMessageConversation('create', {
|
|
5
5
|
resource: 'messageConversations/oXD88WWSQpR'
|
|
6
|
-
})).
|
|
6
|
+
})).toBe(true);
|
|
7
7
|
});
|
|
8
8
|
it('retuns false for a POST to a different resource', () => {
|
|
9
9
|
expect(isReplyToMessageConversation('create', {
|
|
10
10
|
resource: 'test/oXD88WWSQpR'
|
|
11
|
-
})).
|
|
11
|
+
})).toBe(false);
|
|
12
12
|
});
|
|
13
13
|
});
|
|
14
14
|
describe('isCreateFeedbackMessage', () => {
|
|
15
15
|
it('returns true for a POST to "messageConversations/feedback"', () => {
|
|
16
16
|
expect(isCreateFeedbackMessage('create', {
|
|
17
17
|
resource: 'messageConversations/feedback'
|
|
18
|
-
})).
|
|
18
|
+
})).toBe(true);
|
|
19
19
|
});
|
|
20
20
|
it('retuns false for a POST to a different resource', () => {
|
|
21
21
|
expect(isCreateFeedbackMessage('create', {
|
|
22
22
|
resource: 'messageConversations/somethingelse'
|
|
23
|
-
})).
|
|
23
|
+
})).toBe(false);
|
|
24
24
|
});
|
|
25
25
|
});
|
|
26
26
|
describe('isCreateInterpretation', () => {
|
|
27
27
|
it('returns true for a POST to "interpretations/chart/${id}"', () => {
|
|
28
28
|
expect(isCreateInterpretation('create', {
|
|
29
29
|
resource: 'interpretations/chart/oXD88WWSQpR'
|
|
30
|
-
})).
|
|
30
|
+
})).toBe(true);
|
|
31
31
|
});
|
|
32
32
|
it('returns false for a PUT to "interpretations/chart/${id}"', () => {
|
|
33
33
|
expect(isCreateInterpretation('replace', {
|
|
34
34
|
resource: 'interpretations/chart/oXD88WWSQpR'
|
|
35
|
-
})).
|
|
35
|
+
})).toBe(false);
|
|
36
36
|
});
|
|
37
37
|
it('retuns false for PATCH requests with a valid query', () => {
|
|
38
38
|
expect(isCreateInterpretation('update', {
|
|
39
39
|
resource: 'interpretations/chart/oXD88WWSQpR'
|
|
40
|
-
})).
|
|
40
|
+
})).toBe(false);
|
|
41
41
|
});
|
|
42
42
|
it('returns false for a request to a different resource', () => {
|
|
43
43
|
expect(isCreateInterpretation('create', {
|
|
44
44
|
resource: 'interpretations/dummy/oXD88WWSQpR'
|
|
45
|
-
})).
|
|
45
|
+
})).toBe(false);
|
|
46
46
|
});
|
|
47
47
|
});
|
|
48
48
|
describe('isUpdateInterpretation', () => {
|
|
49
49
|
it('returns true for a PUT to "interpretations/${id}"', () => {
|
|
50
50
|
expect(isUpdateInterpretation('replace', {
|
|
51
51
|
resource: 'interpretations/oXD88WWSQpR'
|
|
52
|
-
})).
|
|
52
|
+
})).toBe(true);
|
|
53
53
|
});
|
|
54
54
|
it('returns true for PUT with populated query.id', () => {
|
|
55
55
|
expect(isUpdateInterpretation('replace', {
|
|
56
56
|
resource: 'interpretations',
|
|
57
57
|
id: 'oXD88WWSQpR'
|
|
58
|
-
})).
|
|
58
|
+
})).toBe(true);
|
|
59
59
|
});
|
|
60
60
|
it('returns false for a POST to "interpretations/${id}"', () => {
|
|
61
61
|
expect(isUpdateInterpretation('create', {
|
|
62
62
|
resource: 'interpretations/oXD88WWSQpR'
|
|
63
|
-
})).
|
|
63
|
+
})).toBe(false);
|
|
64
64
|
});
|
|
65
65
|
it('returns false for a PATCH to "interpretations/${id}"', () => {
|
|
66
66
|
expect(isUpdateInterpretation('update', {
|
|
67
67
|
resource: 'interpretations/oXD88WWSQpR'
|
|
68
|
-
})).
|
|
68
|
+
})).toBe(false);
|
|
69
69
|
});
|
|
70
70
|
it('returns false for PATCH with populated query.id', () => {
|
|
71
71
|
expect(isUpdateInterpretation('update', {
|
|
72
72
|
resource: 'interpretations',
|
|
73
73
|
id: 'oXD88WWSQpR'
|
|
74
|
-
})).
|
|
74
|
+
})).toBe(false);
|
|
75
75
|
});
|
|
76
76
|
it('returns false for a request to a different resource', () => {
|
|
77
77
|
expect(isUpdateInterpretation('create', {
|
|
78
78
|
resource: 'interpretations/dummy/oXD88WWSQpR'
|
|
79
|
-
})).
|
|
79
|
+
})).toBe(false);
|
|
80
80
|
});
|
|
81
81
|
});
|
|
82
82
|
describe('isCommentOnInterpretation', () => {
|
|
83
83
|
it('retuns true for POST to `interpretations/${id}/comments`', () => {
|
|
84
84
|
expect(isCommentOnInterpretation('create', {
|
|
85
85
|
resource: 'interpretations/oXD88WWSQpR/comments'
|
|
86
|
-
})).
|
|
86
|
+
})).toBe(true);
|
|
87
87
|
});
|
|
88
88
|
it('retuns false for a POST to a different resource', () => {
|
|
89
89
|
expect(isCommentOnInterpretation('create', {
|
|
90
90
|
resource: 'test/oXD88WWSQpR/comments'
|
|
91
|
-
})).
|
|
91
|
+
})).toBe(false);
|
|
92
92
|
});
|
|
93
93
|
});
|
|
94
94
|
describe('isInterpretationCommentUpdate', () => {
|
|
95
95
|
it('returns true for a PUT to `interpretations/${interpretationId}/comments/${commentId}`', () => {
|
|
96
96
|
expect(isInterpretationCommentUpdate('replace', {
|
|
97
97
|
resource: 'interpretations/oXD88WWSQpR/comments/oXD88WWSQpR'
|
|
98
|
-
})).
|
|
98
|
+
})).toBe(true);
|
|
99
99
|
});
|
|
100
100
|
it('returns true for PUT with populated query.id', () => {
|
|
101
101
|
expect(isInterpretationCommentUpdate('replace', {
|
|
102
102
|
resource: 'interpretations',
|
|
103
103
|
id: 'oXD88WWSQpR/comments/oXD88WWSQpR'
|
|
104
|
-
})).
|
|
104
|
+
})).toBe(true);
|
|
105
105
|
expect(isInterpretationCommentUpdate('replace', {
|
|
106
106
|
resource: 'interpretations/oXD88WWSQpR/comments',
|
|
107
107
|
id: 'oXD88WWSQpR'
|
|
108
|
-
})).
|
|
108
|
+
})).toBe(true);
|
|
109
109
|
});
|
|
110
110
|
it('retuns false for PATCH requests with a valid query', () => {
|
|
111
111
|
expect(isInterpretationCommentUpdate('update', {
|
|
112
112
|
resource: 'interpretations/oXD88WWSQpR/comments/oXD88WWSQpR'
|
|
113
|
-
})).
|
|
113
|
+
})).toBe(false);
|
|
114
114
|
});
|
|
115
115
|
it('returns false for a request to a different resource', () => {
|
|
116
116
|
expect(isInterpretationCommentUpdate('create', {
|
|
117
117
|
resource: 'interpretations/oXD88WWSQpR/dummy/oXD88WWSQpR'
|
|
118
|
-
})).
|
|
118
|
+
})).toBe(false);
|
|
119
119
|
});
|
|
120
120
|
});
|
|
121
121
|
describe('isAddOrUpdateSystemOrUserSetting', () => {
|
|
122
122
|
it('retuns true for POST to `systemSettings/${settingKey}`', () => {
|
|
123
123
|
expect(isAddOrUpdateSystemOrUserSetting('create', {
|
|
124
124
|
resource: 'systemSettings/keyWhatever'
|
|
125
|
-
})).
|
|
125
|
+
})).toBe(true);
|
|
126
126
|
});
|
|
127
127
|
it('retuns true for POST to `userSettings/${settingKey}`', () => {
|
|
128
128
|
expect(isAddOrUpdateSystemOrUserSetting('create', {
|
|
129
129
|
resource: 'userSettings/keyWhatever'
|
|
130
|
-
})).
|
|
130
|
+
})).toBe(true);
|
|
131
131
|
});
|
|
132
132
|
it('retuns false for a POST to a different resource', () => {
|
|
133
133
|
expect(isAddOrUpdateSystemOrUserSetting('create', {
|
|
134
134
|
resource: 'test/keyWhatever'
|
|
135
|
-
})).
|
|
135
|
+
})).toBe(false);
|
|
136
136
|
});
|
|
137
137
|
});
|
|
138
138
|
describe('addOrUpdateConfigurationProperty', () => {
|
|
139
139
|
it('retuns true for POST to `configuration/${property}`', () => {
|
|
140
140
|
expect(addOrUpdateConfigurationProperty('create', {
|
|
141
141
|
resource: 'configuration/whatever'
|
|
142
|
-
})).
|
|
142
|
+
})).toBe(true);
|
|
143
143
|
});
|
|
144
144
|
it('retuns false for POST to `configuration/corsWhitelist`, which needs "application/json"', () => {
|
|
145
145
|
expect(addOrUpdateConfigurationProperty('create', {
|
|
146
146
|
resource: 'configuration/corsWhitelist'
|
|
147
|
-
})).
|
|
147
|
+
})).toBe(false);
|
|
148
148
|
});
|
|
149
149
|
it('retuns false for a POST to a different resource', () => {
|
|
150
150
|
expect(addOrUpdateConfigurationProperty('create', {
|
|
151
151
|
resource: 'test/whatever'
|
|
152
|
-
})).
|
|
152
|
+
})).toBe(false);
|
|
153
153
|
});
|
|
154
154
|
});
|
|
155
155
|
describe('isMetadataPackageInstallation', () => {
|
|
156
156
|
it('returns true for a POST to "synchronization/metadataPull"', () => {
|
|
157
157
|
expect(isMetadataPackageInstallation('create', {
|
|
158
158
|
resource: 'synchronization/metadataPull'
|
|
159
|
-
})).
|
|
159
|
+
})).toBe(true);
|
|
160
160
|
});
|
|
161
161
|
it('retuns false for a POST to a different resource', () => {
|
|
162
162
|
expect(isMetadataPackageInstallation('create', {
|
|
163
163
|
resource: 'synchronization/somethingelse'
|
|
164
|
-
})).
|
|
164
|
+
})).toBe(false);
|
|
165
165
|
});
|
|
166
166
|
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { isSvgConversion } from './xWwwFormUrlencodedMatchers';
|
|
2
|
+
describe('isSvgConversion', () => {
|
|
3
|
+
it('returns true for a POST to "svg.png"', () => {
|
|
4
|
+
expect(isSvgConversion('create', {
|
|
5
|
+
resource: 'svg.png'
|
|
6
|
+
})).toBe(true);
|
|
7
|
+
});
|
|
8
|
+
it('returns true for a POST to "svg.pdf"', () => {
|
|
9
|
+
expect(isSvgConversion('create', {
|
|
10
|
+
resource: 'svg.pdf'
|
|
11
|
+
})).toBe(true);
|
|
12
|
+
});
|
|
13
|
+
it('retuns false for a POST to a different resource', () => {
|
|
14
|
+
expect(isSvgConversion('create', {
|
|
15
|
+
resource: 'notSvg'
|
|
16
|
+
})).toBe(false);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -4,4 +4,3 @@ export declare const isFileResourceUpload: (type: FetchType, { resource }: Resol
|
|
|
4
4
|
export declare const isMessageConversationAttachment: (type: FetchType, { resource }: ResolvedResourceQuery) => boolean;
|
|
5
5
|
export declare const isStaticContentUpload: (type: FetchType, { resource }: ResolvedResourceQuery) => boolean;
|
|
6
6
|
export declare const isAppInstall: (type: FetchType, { resource }: ResolvedResourceQuery) => boolean;
|
|
7
|
-
export declare const isSvgConversion: (type: FetchType, { resource }: ResolvedResourceQuery) => boolean;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ResolvedResourceQuery, FetchType } from '../../../engine';
|
|
2
|
-
declare type RequestContentType = 'application/json' | 'application/json-patch+json' | 'text/plain' | 'multipart/form-data' | null;
|
|
3
|
-
export declare const FORM_DATA_ERROR_MSG = "Could not convert data to FormData: object does not have own enumerable string-keyed properties";
|
|
2
|
+
declare type RequestContentType = 'application/json' | 'application/json-patch+json' | 'text/plain' | 'multipart/form-data' | 'application/x-www-form-urlencoded' | null;
|
|
4
3
|
export declare const requestContentType: (type: FetchType, query: ResolvedResourceQuery) => null | RequestContentType;
|
|
5
4
|
export declare const requestHeadersForContentType: (contentType: RequestContentType) => undefined | Record<'Content-Type', string>;
|
|
6
|
-
export declare const requestBodyForContentType: (contentType: RequestContentType, { data }: ResolvedResourceQuery) => undefined | string | FormData;
|
|
5
|
+
export declare const requestBodyForContentType: (contentType: RequestContentType, { data }: ResolvedResourceQuery) => undefined | string | FormData | URLSearchParams;
|
|
7
6
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dhis2/app-service-data",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"main": "./build/cjs/index.js",
|
|
5
5
|
"module": "./build/es/index.js",
|
|
6
6
|
"types": "build/types/index.d.ts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"build/**"
|
|
23
23
|
],
|
|
24
24
|
"peerDependencies": {
|
|
25
|
-
"@dhis2/app-service-config": "3.
|
|
25
|
+
"@dhis2/app-service-config": "3.5.0",
|
|
26
26
|
"@dhis2/cli-app-scripts": "^7.1.1",
|
|
27
27
|
"prop-types": "^15.7.2",
|
|
28
28
|
"react": "^16.8",
|