@tak-ps/node-tak 12.28.0 → 12.30.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.
@@ -116,6 +116,53 @@ test('Files.upload falls back to application/octet-stream when name has no exten
116
116
  }
117
117
  });
118
118
 
119
+ test('Files.upload passes uid metadata for map item attachments', async () => {
120
+ const originalRequest = Client.prototype.request;
121
+
122
+ let captured: RequestArgs | undefined;
123
+
124
+ Client.prototype.request = async function(opts: RequestArgs): Promise<Dispatcher.ResponseData> {
125
+ captured = opts;
126
+
127
+ return {
128
+ statusCode: 200,
129
+ headers: {
130
+ 'content-type': 'text/plain'
131
+ },
132
+ body: Readable.from([Buffer.from(JSON.stringify({
133
+ UID: 'marker-1',
134
+ SubmissionDateTime: '2026-01-01T00:00:00.000Z',
135
+ Keywords: [],
136
+ MIMEType: 'image/jpeg',
137
+ SubmissionUser: 'user-1',
138
+ PrimaryKey: '2',
139
+ Hash: 'hash-2',
140
+ CreatorUid: 'user-1',
141
+ Name: 'photo.jpg'
142
+ }))]),
143
+ trailers: {}
144
+ } as unknown as Dispatcher.ResponseData;
145
+ };
146
+
147
+ try {
148
+ const api = new TAKAPI(new URL('https://tak.example.com'), new APIAuthCertificate('cert', 'key'));
149
+
150
+ const res = await api.Files.upload({
151
+ name: 'photo.jpg',
152
+ contentLength: 9,
153
+ keywords: [],
154
+ creatorUid: 'user-1',
155
+ uid: 'marker-1'
156
+ }, Buffer.from('jpg-bytes'));
157
+
158
+ assert.equal(res.UID, 'marker-1');
159
+ assert.ok(captured);
160
+ assert.equal(captured.path, '/Marti/sync/upload?name=photo.jpg&keywords=&creatorUid=user-1&uid=marker-1');
161
+ } finally {
162
+ Client.prototype.request = originalRequest;
163
+ }
164
+ });
165
+
119
166
  test('APIAuthPassword surfaces transport causes during login', async () => {
120
167
  const api = new TAKAPI(new URL('https://tak.example.com'), new APIAuthPassword('alice', 'secret'));
121
168
  const originalFetch = api.auth.fetch;
@@ -0,0 +1,207 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { Readable } from 'node:stream';
4
+ import { Client } from 'undici';
5
+ import type { Dispatcher } from 'undici';
6
+ import TAKAPI from '../lib/api.js';
7
+ import { APIAuthCertificate } from '../lib/auth.js';
8
+
9
+ type RequestArgs = Parameters<Client['request']>[0];
10
+
11
+ function mockResponse(statusCode: number, contentType: string, body: string): Dispatcher.ResponseData {
12
+ return {
13
+ statusCode,
14
+ headers: { 'content-type': contentType },
15
+ body: Readable.from([Buffer.from(body)]),
16
+ trailers: {}
17
+ } as unknown as Dispatcher.ResponseData;
18
+ }
19
+
20
+ async function capture(
21
+ fn: (api: TAKAPI) => Promise<unknown>,
22
+ response: Dispatcher.ResponseData = mockResponse(200, 'text/plain', '')
23
+ ): Promise<{ captured: RequestArgs, result: unknown }> {
24
+ const originalRequest = Client.prototype.request;
25
+
26
+ let captured: RequestArgs | undefined;
27
+
28
+ Client.prototype.request = async function(opts: RequestArgs): Promise<Dispatcher.ResponseData> {
29
+ captured = opts;
30
+ return response;
31
+ };
32
+
33
+ try {
34
+ const api = new TAKAPI(new URL('https://tak.example.com'), new APIAuthCertificate('cert', 'key'));
35
+ const result = await fn(api);
36
+ assert.ok(captured);
37
+ return { captured, result };
38
+ } finally {
39
+ Client.prototype.request = originalRequest;
40
+ }
41
+ }
42
+
43
+ test('UserManagement.createUser posts a NewUserModel with defaulted group lists', async () => {
44
+ const { captured } = await capture((api) => api.UserManagement.createUser({
45
+ username: 'alice',
46
+ password: 'Sup3rSecret!',
47
+ groupListIN: ['Blue']
48
+ }));
49
+
50
+ assert.equal(captured.method, 'POST');
51
+ assert.equal(captured.path, '/Marti/api/user-management/api/new-user');
52
+ assert.deepEqual(JSON.parse(String(captured.body)), {
53
+ username: 'alice',
54
+ password: 'Sup3rSecret!',
55
+ groupList: [],
56
+ groupListIN: ['Blue'],
57
+ groupListOUT: []
58
+ });
59
+ });
60
+
61
+ test('UserManagement.createUsers posts a UserGenerationInBulkModel and returns generated credentials', async () => {
62
+ const { captured, result } = await capture(
63
+ (api) => api.UserManagement.createUsers({
64
+ usernameExpression: 'team-[N]',
65
+ startN: 1,
66
+ endN: 2,
67
+ groupList: ['Red']
68
+ }),
69
+ mockResponse(200, 'application/json', JSON.stringify([
70
+ { username: 'team-1', password: 'p1' },
71
+ { username: 'team-2', password: 'p2' }
72
+ ]))
73
+ );
74
+
75
+ assert.equal(captured.method, 'POST');
76
+ assert.equal(captured.path, '/Marti/api/user-management/api/new-users');
77
+ assert.deepEqual(JSON.parse(String(captured.body)), {
78
+ usernameExpression: 'team-[N]',
79
+ startN: 1,
80
+ endN: 2,
81
+ groupList: ['Red'],
82
+ groupListIN: [],
83
+ groupListOUT: []
84
+ });
85
+ assert.deepEqual(result, [
86
+ { username: 'team-1', password: 'p1' },
87
+ { username: 'team-2', password: 'p2' }
88
+ ]);
89
+ });
90
+
91
+ test('UserManagement.listUsers gets list-users', async () => {
92
+ const { captured, result } = await capture(
93
+ (api) => api.UserManagement.listUsers(),
94
+ mockResponse(200, 'application/json', JSON.stringify([{ username: 'alice' }]))
95
+ );
96
+
97
+ assert.equal(captured.method, 'GET');
98
+ assert.equal(captured.path, '/Marti/api/user-management/api/list-users');
99
+ assert.deepEqual(result, [{ username: 'alice' }]);
100
+ });
101
+
102
+ test('UserManagement.userGroups encodes the username in the path', async () => {
103
+ const { captured } = await capture(
104
+ (api) => api.UserManagement.userGroups('a b'),
105
+ mockResponse(200, 'application/json', JSON.stringify({
106
+ username: 'a b', groupList: [], groupListIN: [], groupListOUT: []
107
+ }))
108
+ );
109
+
110
+ assert.equal(captured.method, 'GET');
111
+ assert.equal(captured.path, '/Marti/api/user-management/api/get-groups-for-user/a%20b');
112
+ });
113
+
114
+ test('UserManagement.changePassword puts a UserPasswordModel', async () => {
115
+ const { captured } = await capture((api) => api.UserManagement.changePassword({
116
+ username: 'alice',
117
+ password: 'N3wSecret!'
118
+ }));
119
+
120
+ assert.equal(captured.method, 'PUT');
121
+ assert.equal(captured.path, '/Marti/api/user-management/api/change-user-password');
122
+ assert.deepEqual(JSON.parse(String(captured.body)), {
123
+ username: 'alice',
124
+ password: 'N3wSecret!'
125
+ });
126
+ });
127
+
128
+ test('UserManagement.updateUserGroups puts a SimpleUserGroupModel', async () => {
129
+ const { captured } = await capture((api) => api.UserManagement.updateUserGroups({
130
+ username: 'alice',
131
+ groupList: ['Blue'],
132
+ groupListOUT: ['Red']
133
+ }));
134
+
135
+ assert.equal(captured.method, 'PUT');
136
+ assert.equal(captured.path, '/Marti/api/user-management/api/update-groups');
137
+ assert.deepEqual(JSON.parse(String(captured.body)), {
138
+ username: 'alice',
139
+ groupList: ['Blue'],
140
+ groupListIN: [],
141
+ groupListOUT: ['Red']
142
+ });
143
+ });
144
+
145
+ test('UserManagement.updateGroupUsers puts a SimpleGroupWithUsersModel', async () => {
146
+ const { captured } = await capture((api) => api.UserManagement.updateGroupUsers({
147
+ groupname: 'Blue',
148
+ usersInGroupListIN: ['alice', 'bob']
149
+ }));
150
+
151
+ assert.equal(captured.method, 'PUT');
152
+ assert.equal(captured.path, '/Marti/api/user-management/api/update-group-users');
153
+ assert.deepEqual(JSON.parse(String(captured.body)), {
154
+ groupname: 'Blue',
155
+ usersInGroupList: [],
156
+ usersInGroupListIN: ['alice', 'bob'],
157
+ usersInGroupListOUT: []
158
+ });
159
+ });
160
+
161
+ test('UserManagement.deleteUser deletes by encoded username', async () => {
162
+ const { captured } = await capture((api) => api.UserManagement.deleteUser('a/b'));
163
+
164
+ assert.equal(captured.method, 'DELETE');
165
+ assert.equal(captured.path, '/Marti/api/user-management/api/delete-user/a%2Fb');
166
+ });
167
+
168
+ test('UserManagement.listGroups gets list-groupnames', async () => {
169
+ const { captured, result } = await capture(
170
+ (api) => api.UserManagement.listGroups(),
171
+ mockResponse(200, 'application/json', JSON.stringify([{ groupname: 'Blue' }]))
172
+ );
173
+
174
+ assert.equal(captured.method, 'GET');
175
+ assert.equal(captured.path, '/Marti/api/user-management/api/list-groupnames');
176
+ assert.deepEqual(result, [{ groupname: 'Blue' }]);
177
+ });
178
+
179
+ test('UserManagement.groupUsers gets users-in-group by encoded group name', async () => {
180
+ const { captured, result } = await capture(
181
+ (api) => api.UserManagement.groupUsers('Dark Blue'),
182
+ mockResponse(200, 'application/json', JSON.stringify({
183
+ groupname: 'Dark Blue',
184
+ usersInGroupList: ['alice'],
185
+ usersInGroupListIN: [],
186
+ usersInGroupListOUT: ['bob']
187
+ }))
188
+ );
189
+
190
+ assert.equal(captured.method, 'GET');
191
+ assert.equal(captured.path, '/Marti/api/user-management/api/users-in-group/Dark%20Blue');
192
+ assert.deepEqual(result, {
193
+ groupname: 'Dark Blue',
194
+ usersInGroupList: ['alice'],
195
+ usersInGroupListIN: [],
196
+ usersInGroupListOUT: ['bob']
197
+ });
198
+ });
199
+
200
+ test('UserManagement.cli list-users formats usernames as lines', async () => {
201
+ const { result } = await capture(
202
+ (api) => api.UserManagement.cli({ _: ['tsx', 'cli.ts', 'user-management', 'list-users'] }),
203
+ mockResponse(200, 'application/json', JSON.stringify([{ username: 'alice' }, { username: 'bob' }]))
204
+ );
205
+
206
+ assert.equal(result, 'alice\nbob');
207
+ });