smartling-api-sdk-nodejs 3.5.0 → 3.6.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/.env.example +2 -1
- package/api/estimates/dto/effective-rates-range-dto.ts +7 -0
- package/api/estimates/dto/estimate-report-dto.ts +34 -0
- package/api/estimates/dto/estimate-report-status-dto.ts +13 -0
- package/api/estimates/dto/estimate-report-tags-dto.ts +5 -0
- package/api/estimates/dto/fuzzy-match-tier-dto.ts +17 -0
- package/api/estimates/dto/generated-estimate-report-dto.ts +10 -0
- package/api/estimates/dto/locale-estimate-dto.ts +17 -0
- package/api/estimates/dto/locale-workflow-pair-dto.ts +6 -0
- package/api/estimates/dto/locale-workflow-step-pair-dto.ts +6 -0
- package/api/estimates/dto/price-information-dto.ts +12 -0
- package/api/estimates/dto/workflow-estimate-dto.ts +18 -0
- package/api/estimates/dto/workflow-step-estimate-dto.ts +21 -0
- package/api/estimates/index.ts +102 -0
- package/api/estimates/params/estimate-report-content-coverage.ts +4 -0
- package/api/estimates/params/estimate-report-status.ts +9 -0
- package/api/estimates/params/estimate-report-type.ts +4 -0
- package/api/estimates/params/fuzzy-match-type-code.ts +4 -0
- package/api/estimates/params/generate-job-estimate-report-parameters.ts +46 -0
- package/api/estimates/params/job-content-type.ts +6 -0
- package/api/estimates/params/list-job-estimate-reports-parameters.ts +64 -0
- package/api/estimates/params/modify-estimate-report-tags-parameters.ts +9 -0
- package/built/api/estimates/dto/effective-rates-range-dto.d.ts +6 -0
- package/built/api/estimates/dto/effective-rates-range-dto.js +3 -0
- package/built/api/estimates/dto/effective-rates-range-dto.js.map +1 -0
- package/built/api/estimates/dto/estimate-report-dto.d.ts +30 -0
- package/built/api/estimates/dto/estimate-report-dto.js +3 -0
- package/built/api/estimates/dto/estimate-report-dto.js.map +1 -0
- package/built/api/estimates/dto/estimate-report-status-dto.d.ts +11 -0
- package/built/api/estimates/dto/estimate-report-status-dto.js +3 -0
- package/built/api/estimates/dto/estimate-report-status-dto.js.map +1 -0
- package/built/api/estimates/dto/estimate-report-tags-dto.d.ts +4 -0
- package/built/api/estimates/dto/estimate-report-tags-dto.js +3 -0
- package/built/api/estimates/dto/estimate-report-tags-dto.js.map +1 -0
- package/built/api/estimates/dto/fuzzy-match-tier-dto.d.ts +12 -0
- package/built/api/estimates/dto/fuzzy-match-tier-dto.js +3 -0
- package/built/api/estimates/dto/fuzzy-match-tier-dto.js.map +1 -0
- package/built/api/estimates/dto/generated-estimate-report-dto.d.ts +8 -0
- package/built/api/estimates/dto/generated-estimate-report-dto.js +3 -0
- package/built/api/estimates/dto/generated-estimate-report-dto.js.map +1 -0
- package/built/api/estimates/dto/locale-estimate-dto.d.ts +13 -0
- package/built/api/estimates/dto/locale-estimate-dto.js +3 -0
- package/built/api/estimates/dto/locale-estimate-dto.js.map +1 -0
- package/built/api/estimates/dto/locale-workflow-pair-dto.d.ts +5 -0
- package/built/api/estimates/dto/locale-workflow-pair-dto.js +3 -0
- package/built/api/estimates/dto/locale-workflow-pair-dto.js.map +1 -0
- package/built/api/estimates/dto/locale-workflow-step-pair-dto.d.ts +5 -0
- package/built/api/estimates/dto/locale-workflow-step-pair-dto.js +3 -0
- package/built/api/estimates/dto/locale-workflow-step-pair-dto.js.map +1 -0
- package/built/api/estimates/dto/price-information-dto.d.ts +9 -0
- package/built/api/estimates/dto/price-information-dto.js +3 -0
- package/built/api/estimates/dto/price-information-dto.js.map +1 -0
- package/built/api/estimates/dto/workflow-estimate-dto.d.ts +13 -0
- package/built/api/estimates/dto/workflow-estimate-dto.js +3 -0
- package/built/api/estimates/dto/workflow-estimate-dto.js.map +1 -0
- package/built/api/estimates/dto/workflow-step-estimate-dto.d.ts +17 -0
- package/built/api/estimates/dto/workflow-step-estimate-dto.js +3 -0
- package/built/api/estimates/dto/workflow-step-estimate-dto.js.map +1 -0
- package/built/api/estimates/index.d.ts +23 -0
- package/built/api/estimates/index.js +68 -0
- package/built/api/estimates/index.js.map +1 -0
- package/built/api/estimates/params/estimate-report-content-coverage.d.ts +4 -0
- package/built/api/estimates/params/estimate-report-content-coverage.js +9 -0
- package/built/api/estimates/params/estimate-report-content-coverage.js.map +1 -0
- package/built/api/estimates/params/estimate-report-status.d.ts +9 -0
- package/built/api/estimates/params/estimate-report-status.js +14 -0
- package/built/api/estimates/params/estimate-report-status.js.map +1 -0
- package/built/api/estimates/params/estimate-report-type.d.ts +4 -0
- package/built/api/estimates/params/estimate-report-type.js +9 -0
- package/built/api/estimates/params/estimate-report-type.js.map +1 -0
- package/built/api/estimates/params/fuzzy-match-type-code.d.ts +4 -0
- package/built/api/estimates/params/fuzzy-match-type-code.js +9 -0
- package/built/api/estimates/params/fuzzy-match-type-code.js.map +1 -0
- package/built/api/estimates/params/generate-job-estimate-report-parameters.d.ts +12 -0
- package/built/api/estimates/params/generate-job-estimate-report-parameters.js +32 -0
- package/built/api/estimates/params/generate-job-estimate-report-parameters.js.map +1 -0
- package/built/api/estimates/params/job-content-type.d.ts +6 -0
- package/built/api/estimates/params/job-content-type.js +11 -0
- package/built/api/estimates/params/job-content-type.js.map +1 -0
- package/built/api/estimates/params/list-job-estimate-reports-parameters.d.ts +15 -0
- package/built/api/estimates/params/list-job-estimate-reports-parameters.js +44 -0
- package/built/api/estimates/params/list-job-estimate-reports-parameters.js.map +1 -0
- package/built/api/estimates/params/modify-estimate-report-tags-parameters.d.ts +4 -0
- package/built/api/estimates/params/modify-estimate-report-tags-parameters.js +12 -0
- package/built/api/estimates/params/modify-estimate-report-tags-parameters.js.map +1 -0
- package/built/index.d.ts +21 -0
- package/built/index.js +21 -0
- package/built/index.js.map +1 -1
- package/built/package.json +1 -1
- package/built/test/estimates.spec.d.ts +1 -0
- package/built/test/estimates.spec.js +191 -0
- package/built/test/estimates.spec.js.map +1 -0
- package/built/test/integration/estimates.spec.d.ts +1 -0
- package/built/test/integration/estimates.spec.js +182 -0
- package/built/test/integration/estimates.spec.js.map +1 -0
- package/built/test/integration/helpers/log-response.js +1 -2
- package/built/test/integration/helpers/log-response.js.map +1 -1
- package/index.ts +21 -0
- package/package.json +1 -1
- package/test/estimates.spec.ts +242 -0
- package/test/integration/estimates.spec.ts +271 -0
- package/test/integration/helpers/log-response.ts +5 -3
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import sinon from "sinon";
|
|
2
|
+
import { loggerMock, authMock, responseMock } from "./mock";
|
|
3
|
+
import { SmartlingEstimatesApi } from "../api/estimates/index";
|
|
4
|
+
import { SmartlingAuthApi } from "../api/auth/index";
|
|
5
|
+
import { ListJobEstimateReportsParameters } from "../api/estimates/params/list-job-estimate-reports-parameters";
|
|
6
|
+
import { GenerateJobEstimateReportParameters } from "../api/estimates/params/generate-job-estimate-report-parameters";
|
|
7
|
+
import { ModifyEstimateReportTagsParameters } from "../api/estimates/params/modify-estimate-report-tags-parameters";
|
|
8
|
+
import { EstimateReportStatus } from "../api/estimates/params/estimate-report-status";
|
|
9
|
+
import { EstimateReportContentCoverage } from "../api/estimates/params/estimate-report-content-coverage";
|
|
10
|
+
import { JobContentType } from "../api/estimates/params/job-content-type";
|
|
11
|
+
|
|
12
|
+
describe("SmartlingEstimatesApi class tests.", () => {
|
|
13
|
+
const projectId = "testProjectId";
|
|
14
|
+
const translationJobUid = "testJobUid";
|
|
15
|
+
const reportUid = "testReportUid";
|
|
16
|
+
let estimatesApi;
|
|
17
|
+
let estimatesApiFetchStub;
|
|
18
|
+
let estimatesApiUaStub;
|
|
19
|
+
let responseMockJsonStub;
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
estimatesApi = new SmartlingEstimatesApi(
|
|
23
|
+
"https://test.com", authMock as unknown as SmartlingAuthApi, loggerMock
|
|
24
|
+
);
|
|
25
|
+
estimatesApiFetchStub = sinon.stub(estimatesApi, "fetch");
|
|
26
|
+
estimatesApiUaStub = sinon.stub(estimatesApi, "ua");
|
|
27
|
+
responseMockJsonStub = sinon.stub(responseMock, "json");
|
|
28
|
+
|
|
29
|
+
estimatesApiUaStub.returns("test_user_agent");
|
|
30
|
+
estimatesApiFetchStub.returns(responseMock);
|
|
31
|
+
responseMockJsonStub.returns({
|
|
32
|
+
response: {}
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
afterEach(() => {
|
|
37
|
+
estimatesApiFetchStub.restore();
|
|
38
|
+
responseMockJsonStub.restore();
|
|
39
|
+
estimatesApiUaStub.restore();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe("Methods", () => {
|
|
43
|
+
it("Get job fuzzy estimate reports", async () => {
|
|
44
|
+
const params = new ListJobEstimateReportsParameters()
|
|
45
|
+
.setReportStatus(EstimateReportStatus.COMPLETED)
|
|
46
|
+
.setContentCoverage(EstimateReportContentCoverage.FULL)
|
|
47
|
+
.setCreatorUserUids(["creatorUserUid1"])
|
|
48
|
+
.setTranslationJobSchemaContents([JobContentType.ALL_CONTENT])
|
|
49
|
+
.setTags(["tag1", "tag2"])
|
|
50
|
+
.setCreatedFrom(new Date("2020-01-01T00:00:00.000Z"))
|
|
51
|
+
.setCreatedTo(new Date("2020-02-01T00:00:00.000Z"))
|
|
52
|
+
.setLimit(100)
|
|
53
|
+
.setOffset(10);
|
|
54
|
+
|
|
55
|
+
await estimatesApi.getJobFuzzyEstimateReports(projectId, translationJobUid, params);
|
|
56
|
+
|
|
57
|
+
sinon.assert.calledOnce(estimatesApiFetchStub);
|
|
58
|
+
sinon.assert.calledWithExactly(
|
|
59
|
+
estimatesApiFetchStub,
|
|
60
|
+
`https://test.com/estimates-api/v2/projects/${projectId}/jobs/${translationJobUid}/reports/fuzzy?reportStatus=COMPLETED&contentCoverage=FULL&creatorUserUids=creatorUserUid1&translationJobSchemaContents=ALL_CONTENT&tags=tag1&tags=tag2&createdFrom=2020-01-01T00%3A00%3A00Z&createdTo=2020-02-01T00%3A00%3A00Z&limit=100&offset=10`,
|
|
61
|
+
{
|
|
62
|
+
headers: {
|
|
63
|
+
Authorization: "test_token_type test_access_token",
|
|
64
|
+
"Content-Type": "application/json",
|
|
65
|
+
"User-Agent": "test_user_agent"
|
|
66
|
+
},
|
|
67
|
+
method: "get"
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("Generate job fuzzy estimate report", async () => {
|
|
73
|
+
const params = new GenerateJobEstimateReportParameters()
|
|
74
|
+
.setContentType(JobContentType.ALL_CONTENT)
|
|
75
|
+
.setTags(["tag1"])
|
|
76
|
+
.setLocaleWorkflowStepsFilter([
|
|
77
|
+
{ targetLocaleId: "es-CR", workflowStepUid: "9358c9ed8748" }
|
|
78
|
+
]);
|
|
79
|
+
|
|
80
|
+
await estimatesApi.generateJobFuzzyEstimateReport(projectId, translationJobUid, params);
|
|
81
|
+
|
|
82
|
+
sinon.assert.calledOnce(estimatesApiFetchStub);
|
|
83
|
+
sinon.assert.calledWithExactly(
|
|
84
|
+
estimatesApiFetchStub,
|
|
85
|
+
`https://test.com/estimates-api/v2/projects/${projectId}/jobs/${translationJobUid}/reports/fuzzy`,
|
|
86
|
+
{
|
|
87
|
+
body: "{\"contentType\":\"ALL_CONTENT\",\"tags\":[\"tag1\"],\"localeWorkflowStepsFilter\":[{\"targetLocaleId\":\"es-CR\",\"workflowStepUid\":\"9358c9ed8748\"}]}",
|
|
88
|
+
headers: {
|
|
89
|
+
Authorization: "test_token_type test_access_token",
|
|
90
|
+
"Content-Type": "application/json",
|
|
91
|
+
"User-Agent": "test_user_agent"
|
|
92
|
+
},
|
|
93
|
+
method: "post"
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("Get job cost estimate reports", async () => {
|
|
99
|
+
const params = new ListJobEstimateReportsParameters()
|
|
100
|
+
.setLimit(50)
|
|
101
|
+
.setOffset(0);
|
|
102
|
+
|
|
103
|
+
await estimatesApi.getJobCostEstimateReports(projectId, translationJobUid, params);
|
|
104
|
+
|
|
105
|
+
sinon.assert.calledOnce(estimatesApiFetchStub);
|
|
106
|
+
sinon.assert.calledWithExactly(
|
|
107
|
+
estimatesApiFetchStub,
|
|
108
|
+
`https://test.com/estimates-api/v2/projects/${projectId}/jobs/${translationJobUid}/reports/cost?limit=50&offset=0`,
|
|
109
|
+
{
|
|
110
|
+
headers: {
|
|
111
|
+
Authorization: "test_token_type test_access_token",
|
|
112
|
+
"Content-Type": "application/json",
|
|
113
|
+
"User-Agent": "test_user_agent"
|
|
114
|
+
},
|
|
115
|
+
method: "get"
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("Generate job cost estimate report", async () => {
|
|
121
|
+
const params = new GenerateJobEstimateReportParameters()
|
|
122
|
+
.setContentType(JobContentType.UNAUTHORIZED)
|
|
123
|
+
.setTags(["tag1", "tag2"])
|
|
124
|
+
.setLocaleWorkflows([{ targetLocaleId: "en-FR", workflowUid: "783d9d255523" }])
|
|
125
|
+
.setFuzzyProfileUid("uid123456")
|
|
126
|
+
.setRushRequest(true)
|
|
127
|
+
.setLocaleWorkflowStepsFilter([
|
|
128
|
+
{ targetLocaleId: "es-CR", workflowStepUid: "9358c9ed8748" }
|
|
129
|
+
]);
|
|
130
|
+
|
|
131
|
+
await estimatesApi.generateJobCostEstimateReport(projectId, translationJobUid, params);
|
|
132
|
+
|
|
133
|
+
sinon.assert.calledOnce(estimatesApiFetchStub);
|
|
134
|
+
sinon.assert.calledWithExactly(
|
|
135
|
+
estimatesApiFetchStub,
|
|
136
|
+
`https://test.com/estimates-api/v2/projects/${projectId}/jobs/${translationJobUid}/reports/cost`,
|
|
137
|
+
{
|
|
138
|
+
body: "{\"contentType\":\"UNAUTHORIZED\",\"tags\":[\"tag1\",\"tag2\"],\"localeWorkflows\":[{\"targetLocaleId\":\"en-FR\",\"workflowUid\":\"783d9d255523\"}],\"fuzzyProfileUid\":\"uid123456\",\"rushRequest\":true,\"localeWorkflowStepsFilter\":[{\"targetLocaleId\":\"es-CR\",\"workflowStepUid\":\"9358c9ed8748\"}]}",
|
|
139
|
+
headers: {
|
|
140
|
+
Authorization: "test_token_type test_access_token",
|
|
141
|
+
"Content-Type": "application/json",
|
|
142
|
+
"User-Agent": "test_user_agent"
|
|
143
|
+
},
|
|
144
|
+
method: "post"
|
|
145
|
+
}
|
|
146
|
+
);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("Get estimate report", async () => {
|
|
150
|
+
await estimatesApi.getEstimateReport(projectId, reportUid);
|
|
151
|
+
|
|
152
|
+
sinon.assert.calledOnce(estimatesApiFetchStub);
|
|
153
|
+
sinon.assert.calledWithExactly(
|
|
154
|
+
estimatesApiFetchStub,
|
|
155
|
+
`https://test.com/estimates-api/v2/projects/${projectId}/reports/${reportUid}`,
|
|
156
|
+
{
|
|
157
|
+
headers: {
|
|
158
|
+
Authorization: "test_token_type test_access_token",
|
|
159
|
+
"Content-Type": "application/json",
|
|
160
|
+
"User-Agent": "test_user_agent"
|
|
161
|
+
},
|
|
162
|
+
method: "get"
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("Delete estimate report", async () => {
|
|
168
|
+
await estimatesApi.deleteEstimateReport(projectId, reportUid);
|
|
169
|
+
|
|
170
|
+
sinon.assert.calledOnce(estimatesApiFetchStub);
|
|
171
|
+
sinon.assert.calledWithExactly(
|
|
172
|
+
estimatesApiFetchStub,
|
|
173
|
+
`https://test.com/estimates-api/v2/projects/${projectId}/reports/${reportUid}`,
|
|
174
|
+
{
|
|
175
|
+
headers: {
|
|
176
|
+
Authorization: "test_token_type test_access_token",
|
|
177
|
+
"Content-Type": "application/json",
|
|
178
|
+
"User-Agent": "test_user_agent"
|
|
179
|
+
},
|
|
180
|
+
method: "delete"
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it("Get estimate report status", async () => {
|
|
186
|
+
await estimatesApi.getEstimateReportStatus(projectId, reportUid);
|
|
187
|
+
|
|
188
|
+
sinon.assert.calledOnce(estimatesApiFetchStub);
|
|
189
|
+
sinon.assert.calledWithExactly(
|
|
190
|
+
estimatesApiFetchStub,
|
|
191
|
+
`https://test.com/estimates-api/v2/projects/${projectId}/reports/${reportUid}/status`,
|
|
192
|
+
{
|
|
193
|
+
headers: {
|
|
194
|
+
Authorization: "test_token_type test_access_token",
|
|
195
|
+
"Content-Type": "application/json",
|
|
196
|
+
"User-Agent": "test_user_agent"
|
|
197
|
+
},
|
|
198
|
+
method: "get"
|
|
199
|
+
}
|
|
200
|
+
);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it("Modify estimate report tags", async () => {
|
|
204
|
+
const params = new ModifyEstimateReportTagsParameters().setTags(["AdminJob", "NEWTAG1"]);
|
|
205
|
+
|
|
206
|
+
await estimatesApi.modifyEstimateReportTags(projectId, reportUid, params);
|
|
207
|
+
|
|
208
|
+
sinon.assert.calledOnce(estimatesApiFetchStub);
|
|
209
|
+
sinon.assert.calledWithExactly(
|
|
210
|
+
estimatesApiFetchStub,
|
|
211
|
+
`https://test.com/estimates-api/v2/projects/${projectId}/reports/${reportUid}/tags`,
|
|
212
|
+
{
|
|
213
|
+
body: "{\"tags\":[\"AdminJob\",\"NEWTAG1\"]}",
|
|
214
|
+
headers: {
|
|
215
|
+
Authorization: "test_token_type test_access_token",
|
|
216
|
+
"Content-Type": "application/json",
|
|
217
|
+
"User-Agent": "test_user_agent"
|
|
218
|
+
},
|
|
219
|
+
method: "put"
|
|
220
|
+
}
|
|
221
|
+
);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it("Download estimate report", async () => {
|
|
225
|
+
await estimatesApi.downloadEstimateReport(projectId, reportUid);
|
|
226
|
+
|
|
227
|
+
sinon.assert.calledOnce(estimatesApiFetchStub);
|
|
228
|
+
sinon.assert.calledWithExactly(
|
|
229
|
+
estimatesApiFetchStub,
|
|
230
|
+
`https://test.com/estimates-api/v2/projects/${projectId}/reports/${reportUid}/download?format=csv`,
|
|
231
|
+
{
|
|
232
|
+
headers: {
|
|
233
|
+
Authorization: "test_token_type test_access_token",
|
|
234
|
+
"Content-Type": "application/json",
|
|
235
|
+
"User-Agent": "test_user_agent"
|
|
236
|
+
},
|
|
237
|
+
method: "get"
|
|
238
|
+
}
|
|
239
|
+
);
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
});
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import dotenv from "dotenv";
|
|
2
|
+
import assert from "assert";
|
|
3
|
+
import { SmartlingApiClientBuilder } from "../../api/builder/index";
|
|
4
|
+
import { SmartlingEstimatesApi } from "../../api/estimates/index";
|
|
5
|
+
import { SmartlingJobsApi } from "../../api/jobs/index";
|
|
6
|
+
import { SmartlingProjectsApi } from "../../api/projects/index";
|
|
7
|
+
import { SmartlingFilesApi } from "../../api/files/index";
|
|
8
|
+
import { CreateJobParameters } from "../../api/jobs/params/create-job-parameters";
|
|
9
|
+
import { CancelJobParameters } from "../../api/jobs/params/cancel-job-parameters";
|
|
10
|
+
import { AddFileParameters } from "../../api/jobs/params/add-file-parameters";
|
|
11
|
+
import { AuthorizeJobParameters } from "../../api/jobs/params/authorize-job-parameters";
|
|
12
|
+
import { UploadFileParameters } from "../../api/files/params/upload-file-parameters";
|
|
13
|
+
import { FileType } from "../../api/files/params/file-type";
|
|
14
|
+
import { GenerateJobEstimateReportParameters } from "../../api/estimates/params/generate-job-estimate-report-parameters";
|
|
15
|
+
import { ListJobEstimateReportsParameters } from "../../api/estimates/params/list-job-estimate-reports-parameters";
|
|
16
|
+
import { ModifyEstimateReportTagsParameters } from "../../api/estimates/params/modify-estimate-report-tags-parameters";
|
|
17
|
+
import { JobContentType } from "../../api/estimates/params/job-content-type";
|
|
18
|
+
import { EstimateReportStatus } from "../../api/estimates/params/estimate-report-status";
|
|
19
|
+
import { logResponse } from "./helpers/log-response";
|
|
20
|
+
|
|
21
|
+
dotenv.config();
|
|
22
|
+
|
|
23
|
+
const baseSmartlingApiUrl = process.env.SMARTLING_API_BASE_URL || "https://api.smartling.com";
|
|
24
|
+
const accountUid = process.env.SMARTLING_ACCOUNT_UID as string;
|
|
25
|
+
const userId = process.env.SMARTLING_USER_ID as string;
|
|
26
|
+
const userSecret = process.env.SMARTLING_USER_SECRET as string;
|
|
27
|
+
const hasCredentials = Boolean(accountUid && userId && userSecret);
|
|
28
|
+
|
|
29
|
+
const TERMINAL_REPORT_STATUSES = [
|
|
30
|
+
EstimateReportStatus.COMPLETED,
|
|
31
|
+
EstimateReportStatus.FAILED,
|
|
32
|
+
EstimateReportStatus.TIMEOUT,
|
|
33
|
+
EstimateReportStatus.CANCELED,
|
|
34
|
+
EstimateReportStatus.NOT_FOUND
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
function delay(milliseconds: number): Promise<void> {
|
|
38
|
+
return new Promise((resolve) => {
|
|
39
|
+
setTimeout(resolve, milliseconds);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
describe("SmartlingEstimatesApi integration tests.", function integrationSuite() {
|
|
44
|
+
this.timeout(180000);
|
|
45
|
+
|
|
46
|
+
let estimatesApi: SmartlingEstimatesApi;
|
|
47
|
+
let jobsApi: SmartlingJobsApi;
|
|
48
|
+
let projectsApi: SmartlingProjectsApi;
|
|
49
|
+
let filesApi: SmartlingFilesApi;
|
|
50
|
+
let projectId: string;
|
|
51
|
+
let translationJobUid: string;
|
|
52
|
+
let fileUri: string;
|
|
53
|
+
let fuzzyReportUid: string | undefined;
|
|
54
|
+
let costReportUid: string | undefined;
|
|
55
|
+
|
|
56
|
+
before(function skipWithoutCredentials() {
|
|
57
|
+
if (!hasCredentials) {
|
|
58
|
+
// eslint-disable-next-line no-console
|
|
59
|
+
console.log("Skipping Estimates integration tests: set SMARTLING_ACCOUNT_UID, SMARTLING_USER_ID, SMARTLING_USER_SECRET in .env");
|
|
60
|
+
this.skip();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
estimatesApi = new SmartlingApiClientBuilder()
|
|
64
|
+
.setBaseSmartlingApiUrl(baseSmartlingApiUrl)
|
|
65
|
+
.authWithUserIdAndUserSecret(userId, userSecret)
|
|
66
|
+
.build(SmartlingEstimatesApi);
|
|
67
|
+
|
|
68
|
+
jobsApi = new SmartlingApiClientBuilder()
|
|
69
|
+
.setBaseSmartlingApiUrl(baseSmartlingApiUrl)
|
|
70
|
+
.authWithUserIdAndUserSecret(userId, userSecret)
|
|
71
|
+
.build(SmartlingJobsApi);
|
|
72
|
+
|
|
73
|
+
projectsApi = new SmartlingApiClientBuilder()
|
|
74
|
+
.setBaseSmartlingApiUrl(baseSmartlingApiUrl)
|
|
75
|
+
.authWithUserIdAndUserSecret(userId, userSecret)
|
|
76
|
+
.build(SmartlingProjectsApi);
|
|
77
|
+
|
|
78
|
+
filesApi = new SmartlingApiClientBuilder()
|
|
79
|
+
.setBaseSmartlingApiUrl(baseSmartlingApiUrl)
|
|
80
|
+
.authWithUserIdAndUserSecret(userId, userSecret)
|
|
81
|
+
.build(SmartlingFilesApi);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
before(async () => {
|
|
85
|
+
const projects = await projectsApi.listProjects(accountUid);
|
|
86
|
+
|
|
87
|
+
logResponse("listProjects", projects);
|
|
88
|
+
assert.ok(projects.items.length > 0, "Test account must have at least one project to run Estimates integration tests");
|
|
89
|
+
|
|
90
|
+
({ projectId } = projects.items[0]);
|
|
91
|
+
|
|
92
|
+
const project = await projectsApi.getProjectDetails(projectId);
|
|
93
|
+
|
|
94
|
+
logResponse("getProjectDetails", project);
|
|
95
|
+
|
|
96
|
+
const targetLocaleIds = project.targetLocales.map((locale) => locale.localeId);
|
|
97
|
+
|
|
98
|
+
const job = await jobsApi.createJob(
|
|
99
|
+
projectId,
|
|
100
|
+
new CreateJobParameters()
|
|
101
|
+
.setName(`api-sdk-nodejs estimates integration test ${Date.now()}`)
|
|
102
|
+
.setTargetLocaleIds(targetLocaleIds)
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
logResponse("createJob", job);
|
|
106
|
+
({ translationJobUid } = job);
|
|
107
|
+
|
|
108
|
+
// Real translatable content, so the generated reports have non-zero word counts and
|
|
109
|
+
// a populated locale/workflow/fuzzy-match breakdown to verify the nested DTOs against.
|
|
110
|
+
fileUri = `api-sdk-nodejs-estimates-integration-test-${Date.now()}.json`;
|
|
111
|
+
|
|
112
|
+
const uploaded = await filesApi.uploadFile(
|
|
113
|
+
projectId,
|
|
114
|
+
new UploadFileParameters()
|
|
115
|
+
.setFileUri(fileUri)
|
|
116
|
+
.setFileType(FileType.JSON)
|
|
117
|
+
.setFileContent(JSON.stringify({
|
|
118
|
+
greeting: "Hello, welcome to our service!",
|
|
119
|
+
farewell: "Thank you for using our application, we hope to see you again soon.",
|
|
120
|
+
description: "This is a sample piece of content used to generate a translation estimate for integration testing purposes."
|
|
121
|
+
}))
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
logResponse("uploadFile", uploaded);
|
|
125
|
+
|
|
126
|
+
const addedFile = await jobsApi.addFileToJob(
|
|
127
|
+
projectId,
|
|
128
|
+
translationJobUid,
|
|
129
|
+
new AddFileParameters().setFileUri(fileUri).setTargetLocaleIds(targetLocaleIds)
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
logResponse("addFileToJob", addedFile);
|
|
133
|
+
|
|
134
|
+
// Assigns the project's default workflow per locale, so the estimate has a workflow
|
|
135
|
+
// to break the word counts down by.
|
|
136
|
+
const authorized = await jobsApi.authorizeJob(
|
|
137
|
+
projectId, translationJobUid, new AuthorizeJobParameters()
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
logResponse("authorizeJob", authorized);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
after(async () => {
|
|
144
|
+
// Guards against a leaked report if an assertion in the `it` block below threw before
|
|
145
|
+
// reaching that test's own deleteEstimateReport call - each test clears its tracked uid
|
|
146
|
+
// once it deletes the report itself, so this is a no-op on the happy path.
|
|
147
|
+
if (fuzzyReportUid) {
|
|
148
|
+
await estimatesApi.deleteEstimateReport(projectId, fuzzyReportUid);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (costReportUid) {
|
|
152
|
+
await estimatesApi.deleteEstimateReport(projectId, costReportUid);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (translationJobUid) {
|
|
156
|
+
// A job can only be deleted once it's CANCELLED.
|
|
157
|
+
await jobsApi.cancelJob(
|
|
158
|
+
projectId,
|
|
159
|
+
translationJobUid,
|
|
160
|
+
new CancelJobParameters().setReason("api-sdk-nodejs integration test cleanup")
|
|
161
|
+
);
|
|
162
|
+
await jobsApi.deleteJob(projectId, translationJobUid);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (fileUri) {
|
|
166
|
+
await filesApi.deleteFile(projectId, fileUri);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
async function waitForReportCompletion(reportUid: string): Promise<void> {
|
|
171
|
+
for (let attempt = 0; attempt < 30; attempt += 1) {
|
|
172
|
+
/* eslint-disable-next-line no-await-in-loop */
|
|
173
|
+
const status = await estimatesApi.getEstimateReportStatus(projectId, reportUid);
|
|
174
|
+
|
|
175
|
+
logResponse("getEstimateReportStatus", status);
|
|
176
|
+
|
|
177
|
+
if (TERMINAL_REPORT_STATUSES.includes(status.reportStatus)) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/* eslint-disable-next-line no-await-in-loop */
|
|
182
|
+
await delay(3000);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
throw new Error(`Timed out waiting for report ${reportUid} to complete`);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
it("generates, reads, lists, tags, downloads and deletes a fuzzy estimate report", async () => {
|
|
189
|
+
const generated = await estimatesApi.generateJobFuzzyEstimateReport(
|
|
190
|
+
projectId,
|
|
191
|
+
translationJobUid,
|
|
192
|
+
new GenerateJobEstimateReportParameters().setContentType(JobContentType.ALL_CONTENT)
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
logResponse("generateJobFuzzyEstimateReport", generated);
|
|
196
|
+
assert.ok(generated.reportUid);
|
|
197
|
+
|
|
198
|
+
const { reportUid } = generated;
|
|
199
|
+
|
|
200
|
+
fuzzyReportUid = reportUid;
|
|
201
|
+
|
|
202
|
+
await waitForReportCompletion(reportUid);
|
|
203
|
+
|
|
204
|
+
const report = await estimatesApi.getEstimateReport(projectId, reportUid);
|
|
205
|
+
|
|
206
|
+
logResponse("getEstimateReport", report);
|
|
207
|
+
assert.equal(report.reportUid, reportUid);
|
|
208
|
+
assert.ok(report.totalStrings > 0, "expected non-zero totalStrings now the job has real content");
|
|
209
|
+
|
|
210
|
+
const list = await estimatesApi.getJobFuzzyEstimateReports(
|
|
211
|
+
projectId,
|
|
212
|
+
translationJobUid,
|
|
213
|
+
new ListJobEstimateReportsParameters().setLimit(10).setOffset(0)
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
logResponse("getJobFuzzyEstimateReports", list);
|
|
217
|
+
assert.ok(list.items.some((item) => item.reportUid === reportUid));
|
|
218
|
+
|
|
219
|
+
const tagged = await estimatesApi.modifyEstimateReportTags(
|
|
220
|
+
projectId,
|
|
221
|
+
reportUid,
|
|
222
|
+
new ModifyEstimateReportTagsParameters().setTags(["api-sdk-nodejs-integration"])
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
logResponse("modifyEstimateReportTags", tagged);
|
|
226
|
+
assert.deepEqual(tagged.tags, ["api-sdk-nodejs-integration"]);
|
|
227
|
+
|
|
228
|
+
const downloaded = await estimatesApi.downloadEstimateReport(projectId, reportUid);
|
|
229
|
+
|
|
230
|
+
logResponse("downloadEstimateReport", `<${downloaded.byteLength} bytes>`);
|
|
231
|
+
assert.ok(downloaded.byteLength > 0);
|
|
232
|
+
|
|
233
|
+
await estimatesApi.deleteEstimateReport(projectId, reportUid);
|
|
234
|
+
fuzzyReportUid = undefined;
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it("generates and reads a cost estimate report", async () => {
|
|
238
|
+
const generated = await estimatesApi.generateJobCostEstimateReport(
|
|
239
|
+
projectId,
|
|
240
|
+
translationJobUid,
|
|
241
|
+
new GenerateJobEstimateReportParameters().setContentType(JobContentType.ALL_CONTENT)
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
logResponse("generateJobCostEstimateReport", generated);
|
|
245
|
+
assert.ok(generated.reportUid);
|
|
246
|
+
|
|
247
|
+
const { reportUid } = generated;
|
|
248
|
+
|
|
249
|
+
costReportUid = reportUid;
|
|
250
|
+
|
|
251
|
+
await waitForReportCompletion(reportUid);
|
|
252
|
+
|
|
253
|
+
const report = await estimatesApi.getEstimateReport(projectId, reportUid);
|
|
254
|
+
|
|
255
|
+
logResponse("getEstimateReport (cost)", report);
|
|
256
|
+
assert.equal(report.reportUid, reportUid);
|
|
257
|
+
assert.ok(report.totalStrings > 0, "expected non-zero totalStrings now the job has real content");
|
|
258
|
+
|
|
259
|
+
const list = await estimatesApi.getJobCostEstimateReports(
|
|
260
|
+
projectId,
|
|
261
|
+
translationJobUid,
|
|
262
|
+
new ListJobEstimateReportsParameters().setLimit(10).setOffset(0)
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
logResponse("getJobCostEstimateReports", list);
|
|
266
|
+
assert.ok(list.items.some((item) => item.reportUid === reportUid));
|
|
267
|
+
|
|
268
|
+
await estimatesApi.deleteEstimateReport(projectId, reportUid);
|
|
269
|
+
costReportUid = undefined;
|
|
270
|
+
});
|
|
271
|
+
});
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
const logResponsesEnabled = process.env.SMARTLING_LOG_RESPONSES === "true";
|
|
2
|
-
|
|
3
1
|
export function logResponse(label: string, response: unknown): void {
|
|
4
|
-
|
|
2
|
+
// Read fresh on every call rather than freezing into a module-level constant at import
|
|
3
|
+
// time: this module is `require`d (by each spec file's own imports) before that same
|
|
4
|
+
// spec file's `dotenv.config()` call runs, and the require is cached - so a constant
|
|
5
|
+
// computed once here would always see pre-dotenv env vars, regardless of .env's content.
|
|
6
|
+
if (process.env.SMARTLING_LOG_RESPONSES !== "true") {
|
|
5
7
|
return;
|
|
6
8
|
}
|
|
7
9
|
|