Skip to content

Commit 38700aa

Browse files
authored
Merge pull request #147 from Smartling/MCPSRV-43-vendor-content-assignments
MCPSRV-43: add Vendors getContentAssignmentsByAccount client
2 parents 19af642 + 4bad6e0 commit 38700aa

8 files changed

Lines changed: 218 additions & 3 deletions

File tree

api/base/base-api.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,9 @@ export class SmartlingBaseApi {
164164
"actionTime",
165165
"publishDate",
166166
"lastModified",
167-
"attemptDate"
167+
"attemptDate",
168+
"translationJobWorkflowStepDueDate",
169+
"translationJobOverallDueDate"
168170
];
169171

170172
if (dateProperties.includes(key) && value) {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
interface SmartlingBareListResponse<T> {
2+
items: Array<T>;
3+
}
4+
5+
export { SmartlingBareListResponse };
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
interface SmartlingListResponse<T> {
1+
import { SmartlingBareListResponse } from "./smartling-bare-list-response";
2+
3+
interface SmartlingListResponse<T> extends SmartlingBareListResponse<T> {
24
totalCount: number;
3-
items: Array<T>;
45
}
56

67
export { SmartlingListResponse };
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { WorkflowStepType } from "./workflow-step-type";
2+
3+
interface ContentAssignmentDto {
4+
accountUid: string;
5+
accountName: string;
6+
projectUid: string;
7+
projectName: string;
8+
localeId: string;
9+
workflowUid: string;
10+
workflowName: string;
11+
workflowStepUid: string;
12+
workflowStepName: string;
13+
workflowStepType: WorkflowStepType;
14+
translationJobUid: string;
15+
translationJobName: string;
16+
translationJobWorkflowStepDueDate: Date;
17+
translationJobOverallDueDate: Date;
18+
userUid: string | null;
19+
userFirstName: string | null;
20+
userLastName: string | null;
21+
userEmail: string | null;
22+
agencyUid: string | null;
23+
agencyName: string | null;
24+
wordCount: number;
25+
workflowStepOrder: number;
26+
assignmentEnabled: boolean;
27+
}
28+
29+
export { ContentAssignmentDto };
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
enum WorkflowStepType {
2+
AWAITING_AUTHORIZATION = "AWAITING_AUTHORIZATION",
3+
ANALYSIS = "ANALYSIS",
4+
WORK_APPROVAL = "WORK_APPROVAL",
5+
TRANSLATION = "TRANSLATION",
6+
POST_TRANSLATION__EDIT = "POST_TRANSLATION__EDIT",
7+
POST_TRANSLATION__REVIEW = "POST_TRANSLATION__REVIEW",
8+
ADMIN_APPROVAL = "ADMIN_APPROVAL",
9+
PUBLISH = "PUBLISH",
10+
POST_TRANSLATION__MONOLINGUAL_REVIEW = "POST_TRANSLATION__MONOLINGUAL_REVIEW",
11+
POST_TRANSLATION__POST_MACHINE_REVISION = "POST_TRANSLATION__POST_MACHINE_REVISION",
12+
POST_TRANSLATION__POST_MACHINE_REVISION_PRO = "POST_TRANSLATION__POST_MACHINE_REVISION_PRO"
13+
}
14+
15+
export { WorkflowStepType };

api/vendors/index.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { SmartlingBaseApi } from "../base/index";
2+
import { AccessTokenProvider } from "../auth/access-token-provider";
3+
import { Logger } from "../logger";
4+
import { ContentAssignmentDto } from "./dto/content-assignment-dto";
5+
import { SmartlingBareListResponse } from "../http/smartling-bare-list-response";
6+
7+
export class SmartlingVendorsApi extends SmartlingBaseApi {
8+
constructor(smartlingApiBaseUrl: string, authApi: AccessTokenProvider, logger: Logger) {
9+
super(logger);
10+
11+
this.authApi = authApi;
12+
this.entrypoint = `${smartlingApiBaseUrl}/vendors-api/v2`;
13+
}
14+
15+
public async getContentAssignmentsByAccount(
16+
accountUid: string
17+
): Promise<SmartlingBareListResponse<ContentAssignmentDto>> {
18+
return await this.makeRequest(
19+
"get",
20+
`${this.entrypoint}/accounts/${accountUid}/content-assignments`
21+
);
22+
}
23+
}

index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,7 @@ export * from "./api/reports/dto/word-count-dto";
179179
export * from "./api/reports/params/word-count-parameters";
180180
export * from "./api/reports/params/date-formatter";
181181
export * from "./api/webhooks";
182+
export * from "./api/http/smartling-bare-list-response";
183+
export * from "./api/vendors/index";
184+
export * from "./api/vendors/dto/content-assignment-dto";
185+
export * from "./api/vendors/dto/workflow-step-type";

test/vendors.spec.ts

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import sinon from "sinon";
2+
import assert from "assert";
3+
import { SmartlingVendorsApi } from "../api/vendors";
4+
import { SmartlingAuthApi } from "../api/auth/index";
5+
import { WorkflowStepType } from "../api/vendors/dto/workflow-step-type";
6+
import { loggerMock, authMock, responseMock } from "./mock";
7+
8+
describe("SmartlingVendorsApi class tests.", () => {
9+
let vendorsApi;
10+
let vendorsApiFetchStub;
11+
let vendorsApiUaStub;
12+
let responseMockTextStub;
13+
14+
beforeEach(() => {
15+
vendorsApi = new SmartlingVendorsApi("https://test.com", authMock as unknown as SmartlingAuthApi, loggerMock);
16+
17+
vendorsApiFetchStub = sinon.stub(vendorsApi, "fetch");
18+
vendorsApiUaStub = sinon.stub(vendorsApi, "ua");
19+
responseMockTextStub = sinon.stub(responseMock, "text");
20+
21+
vendorsApiUaStub.returns("test_user_agent");
22+
vendorsApiFetchStub.returns(responseMock);
23+
responseMockTextStub.returns("{\"response\": {\"data\": {\"items\": []}}}");
24+
});
25+
26+
afterEach(() => {
27+
vendorsApiFetchStub.restore();
28+
responseMockTextStub.restore();
29+
vendorsApiUaStub.restore();
30+
});
31+
32+
it("Get content assignments by account", async () => {
33+
await vendorsApi.getContentAssignmentsByAccount("test_account");
34+
35+
sinon.assert.calledOnce(vendorsApiFetchStub);
36+
sinon.assert.calledWithExactly(
37+
vendorsApiFetchStub,
38+
"https://test.com/vendors-api/v2/accounts/test_account/content-assignments",
39+
{
40+
headers: {
41+
Authorization: "test_token_type test_access_token",
42+
"Content-Type": "application/json",
43+
"User-Agent": "test_user_agent"
44+
},
45+
method: "get"
46+
}
47+
);
48+
});
49+
50+
it("Parses due date fields as Date instances", async () => {
51+
responseMockTextStub.returns(JSON.stringify({
52+
response: {
53+
data: {
54+
items: [{
55+
accountUid: "a1",
56+
accountName: "A",
57+
projectUid: "p1",
58+
projectName: "P",
59+
localeId: "es-ES",
60+
workflowUid: "w1",
61+
workflowName: "W",
62+
workflowStepUid: "ws1",
63+
workflowStepName: "Translation",
64+
workflowStepType: "TRANSLATION",
65+
translationJobUid: "j1",
66+
translationJobName: "J",
67+
translationJobWorkflowStepDueDate: "2025-01-20T18:01:00Z",
68+
translationJobOverallDueDate: "2025-01-21T18:01:00Z",
69+
userUid: null,
70+
userFirstName: null,
71+
userLastName: null,
72+
userEmail: null,
73+
agencyUid: null,
74+
agencyName: null,
75+
wordCount: 300,
76+
workflowStepOrder: 2,
77+
assignmentEnabled: false
78+
}]
79+
}
80+
}
81+
}));
82+
83+
const result = await vendorsApi.getContentAssignmentsByAccount("test_account");
84+
const item = result.items[0];
85+
86+
assert.ok(item.translationJobWorkflowStepDueDate instanceof Date);
87+
assert.equal(item.translationJobWorkflowStepDueDate.toISOString(), "2025-01-20T18:01:00.000Z");
88+
assert.ok(item.translationJobOverallDueDate instanceof Date);
89+
assert.equal(item.translationJobOverallDueDate.toISOString(), "2025-01-21T18:01:00.000Z");
90+
assert.equal(item.workflowStepType, WorkflowStepType.TRANSLATION);
91+
});
92+
93+
it("Preserves null user and agency fields", async () => {
94+
responseMockTextStub.returns(JSON.stringify({
95+
response: {
96+
data: {
97+
items: [{
98+
accountUid: "a1",
99+
accountName: "A",
100+
projectUid: "p1",
101+
projectName: "P",
102+
localeId: "es-ES",
103+
workflowUid: "w1",
104+
workflowName: "W",
105+
workflowStepUid: "ws1",
106+
workflowStepName: "Translation",
107+
workflowStepType: "TRANSLATION",
108+
translationJobUid: "j1",
109+
translationJobName: "J",
110+
translationJobWorkflowStepDueDate: "2025-01-20T18:01:00Z",
111+
translationJobOverallDueDate: "2025-01-21T18:01:00Z",
112+
userUid: null,
113+
userFirstName: null,
114+
userLastName: null,
115+
userEmail: null,
116+
agencyUid: null,
117+
agencyName: null,
118+
wordCount: 0,
119+
workflowStepOrder: 1,
120+
assignmentEnabled: true
121+
}]
122+
}
123+
}
124+
}));
125+
126+
const result = await vendorsApi.getContentAssignmentsByAccount("test_account");
127+
const item = result.items[0];
128+
129+
assert.strictEqual(item.userUid, null);
130+
assert.strictEqual(item.userFirstName, null);
131+
assert.strictEqual(item.userLastName, null);
132+
assert.strictEqual(item.userEmail, null);
133+
assert.strictEqual(item.agencyUid, null);
134+
assert.strictEqual(item.agencyName, null);
135+
});
136+
});

0 commit comments

Comments
 (0)