Skip to content

Commit 912f2ab

Browse files
committed
added user command
1 parent 9d26bd6 commit 912f2ab

File tree

9 files changed

+214
-19
lines changed

9 files changed

+214
-19
lines changed

bin/main.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const {
1010
listPastes,
1111
loginUser,
1212
logout,
13+
getUserInfo,
1314
} = require('../lib/api-functions.js');
1415

1516
let userToken;
@@ -135,5 +136,13 @@ yargs(hideBin(process.argv))
135136
console.log(response);
136137
}
137138
)
139+
.command(
140+
'user',
141+
'shows info about currently logged in user',
142+
() => {},
143+
async () => {
144+
console.log(await getUserInfo(apiToken, userToken));
145+
}
146+
)
138147
.demandCommand(1)
139148
.parse();

lib/api-functions.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@ const { API_URLS, FORMAT_CHOICES } = require('./constant.js');
44
const { readFileSync, rmSync, writeFileSync, existsSync } = require('fs');
55
const { homedir } = require('os');
66
const { table } = require('table');
7-
const { getListTable, mapToVisiblityCode, tokenGuard } = require('./util.js');
7+
const {
8+
getListTable,
9+
mapToVisiblityCode,
10+
tokenGuard,
11+
getUserData,
12+
} = require('./util.js');
813

914
module.exports = {
1015
loginUser,
1116
listPastes,
1217
logout,
1318
deletePaste,
1419
createPaste,
20+
getUserInfo,
1521
};
1622

1723
async function loginUser(argv, apiToken) {
@@ -145,3 +151,25 @@ async function createPaste(argv, apiToken, userToken) {
145151

146152
return response.status === 200 ? `Success! ${text}` : `Error! ${text}`;
147153
}
154+
155+
async function getUserInfo(apiToken, userToken) {
156+
if (tokenGuard(apiToken)) {
157+
return 'Please provide your pastebin.com API token in the ~/.pasty.api file.';
158+
}
159+
160+
if (tokenGuard(userToken)) {
161+
return 'Please login first via pasty login <username>';
162+
}
163+
164+
const response = await fetch(API_URLS.apiPost, {
165+
body: `api_dev_key=${apiToken}&api_user_key=${userToken}&api_option=userdetails`,
166+
headers: {
167+
'Content-Type': 'application/x-www-form-urlencoded',
168+
},
169+
method: 'POST',
170+
});
171+
172+
const text = await response.text();
173+
174+
return response.status === 200 ? table(getUserData(text)) : `Error! ${text}`;
175+
}

lib/constant.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
module.exports = {
2-
TABLE_HEADERS: [
2+
LIST_TABLE_HEADERS: [
33
'paste id',
44
'paste name',
55
'paste visibilty',
66
'paste expiry',
77
'paste syntax highlighting',
88
],
9+
USER_TABLE_HEADERS: [
10+
'user name',
11+
'account visibility',
12+
'user email',
13+
'account type',
14+
],
915
PASTE_LIST_KEYS: {
1016
key: 'paste_key',
1117
title: 'paste_title',

lib/util.js

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
const { TABLE_HEADERS, PASTE_LIST_KEYS } = require('./constant.js');
1+
const {
2+
LIST_TABLE_HEADERS,
3+
PASTE_LIST_KEYS,
4+
USER_TABLE_HEADERS,
5+
} = require('./constant.js');
26
const { JSDOM } = require('jsdom');
37

48
module.exports = {
@@ -7,6 +11,9 @@ module.exports = {
711
convertToDate,
812
tokenGuard,
913
getListTable,
14+
getUserData,
15+
mapAccountPremium,
16+
mapAccountVisibility,
1017
};
1118

1219
function mapToVisibilityString(code) {
@@ -57,7 +64,7 @@ function tokenGuard(token) {
5764

5865
function getListTable(xmlData) {
5966
const tableData = [];
60-
tableData.push(TABLE_HEADERS);
67+
tableData.push(LIST_TABLE_HEADERS);
6168

6269
const xmlResponse = new JSDOM(xmlData);
6370

@@ -83,3 +90,42 @@ function getListTable(xmlData) {
8390

8491
return tableData;
8592
}
93+
94+
function getUserData(xml) {
95+
const tableData = [];
96+
tableData.push(USER_TABLE_HEADERS);
97+
98+
const xmlResponse = new JSDOM(xml);
99+
100+
const user = xmlResponse.window.document.querySelector('user');
101+
const userName = user.querySelector('user_name').textContent;
102+
const privacy = user.querySelector('user_private').textContent;
103+
const email = user.querySelector('user_email').textContent;
104+
const premium = user.querySelector('user_account_type').textContent;
105+
106+
tableData.push([
107+
userName,
108+
mapAccountVisibility(privacy),
109+
email,
110+
mapAccountPremium(premium),
111+
]);
112+
113+
return tableData;
114+
}
115+
116+
function mapAccountPremium(code) {
117+
return Number(code) === 0 ? 'free' : 'premium';
118+
}
119+
120+
function mapAccountVisibility(code) {
121+
switch (Number(code)) {
122+
case 0:
123+
return 'public';
124+
case 1:
125+
return 'unlisted';
126+
case 2:
127+
return 'private';
128+
default:
129+
return 'error, could not get from api';
130+
}
131+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "pasty",
3-
"version": "1.0.0",
3+
"version": "1.1.0",
44
"description": "a cli for pastebin.com",
55
"main": "lib/main.js",
66
"directories": {

tests/__mocks__/node-fetch.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
const { getXml } = require('./../helper/test-helper');
1+
const { getPasteListXml, getUserXml } = require('./../helper/test-helper');
22

33
let fetch;
44

55
let statusCode = 200;
66
let responseText;
77

8-
function mockFetch(url) {
8+
function mockFetch(url, options) {
99
return Promise.resolve({
1010
status: statusCode,
1111
text: () =>
1212
responseText
1313
? responseText
14-
: getXml('paste key', 'paste name', '0', '0', 'text'),
14+
: options.body.includes('api_option=list')
15+
? getPasteListXml('paste key', 'paste name', '0', '0', 'text')
16+
: getUserXml('test user', '2', '[email protected]', '0'),
1517
});
1618
}
1719

tests/api-functions.spec.js

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ const {
88
createPaste,
99
logout,
1010
loginUser,
11+
getUserInfo,
1112
} = require('../lib/api-functions');
12-
const { TABLE_HEADERS } = require('../lib/constant');
13+
const { LIST_TABLE_HEADERS, USER_TABLE_HEADERS } = require('../lib/constant');
1314
const { table } = require('table');
1415
const { __setStatusCode, __setResponseText } = require('node-fetch');
1516
const fs = require('fs');
@@ -49,7 +50,7 @@ describe('apiFunctions', () => {
4950
// is even worse because of newlines, etc.
5051
expect(actualResponse).toBe(
5152
table([
52-
[...TABLE_HEADERS],
53+
[...LIST_TABLE_HEADERS],
5354
['paste key', 'paste name', 'public', 'Never', 'text'], // values set in node-fetch.js mock
5455
])
5556
);
@@ -275,3 +276,42 @@ describe('apiFunctions', () => {
275276
});
276277
});
277278
});
279+
280+
describe('getUserInfo', () => {
281+
testTokenGuard(
282+
true,
283+
getUserInfo,
284+
[undefined, 'user token'],
285+
'Please provide your pastebin.com API token in the ~/.pasty.api file.'
286+
);
287+
288+
testTokenGuard(
289+
false,
290+
getUserInfo,
291+
['api token', undefined],
292+
'Please login first via pasty login <username>'
293+
);
294+
295+
it('should return table with correct data', async () => {
296+
__setResponseText(undefined);
297+
__setStatusCode(200);
298+
299+
const actualResponse = await getUserInfo('token', 'another token');
300+
301+
expect(actualResponse).toBe(
302+
table([
303+
[...USER_TABLE_HEADERS],
304+
['test user', 'private', '[email protected]', 'free'], // actual values set in node-fetch.mock
305+
])
306+
);
307+
});
308+
309+
it('should return error if api returns error', async () => {
310+
__setResponseText('Wrong api key');
311+
__setStatusCode(304);
312+
313+
const actualResponse = await getUserInfo('token', 'another token');
314+
315+
expect(actualResponse).toBe('Error! Wrong api key');
316+
});
317+
});

tests/helper/test-helper.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function getXml(
1+
function getPasteListXml(
22
pasteKey,
33
pasteName,
44
pasteVisibility,
@@ -21,6 +21,23 @@ function getXml(
2121
`;
2222
}
2323

24+
function getUserXml(userName, privacy, email, premium) {
25+
return `
26+
<user>
27+
<user_name>${userName}</user_name>
28+
<user_format_short>text</user_format_short>
29+
<user_expiration>N</user_expiration>
30+
<user_avatar_url>https://pastebin.com/cache/a/1.jpg</user_avatar_url>
31+
<user_private>${privacy}</user_private>
32+
<user_website>https://myawesomesite.com</user_website>
33+
<user_email>${email}</user_email>
34+
<user_location>New York</user_location>
35+
<user_account_type>${premium}</user_account_type>
36+
</user>
37+
`;
38+
}
39+
2440
module.exports = {
25-
getXml,
41+
getPasteListXml,
42+
getUserXml,
2643
};

tests/util.spec.js

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
const { TABLE_HEADERS } = require('../lib/constant');
1+
const { LIST_TABLE_HEADERS, USER_TABLE_HEADERS } = require('../lib/constant');
22
const {
33
convertToDate,
44
getListTable,
55
mapToVisibilityString,
66
mapToVisiblityCode,
77
tokenGuard,
8+
mapAccountPremium,
9+
mapAccountVisibility,
10+
getUserData,
811
} = require('../lib/util');
9-
const { getXml } = require('./helper/test-helper');
12+
const { getPasteListXml, getUserXml } = require('./helper/test-helper');
1013

1114
describe('mapToVisibilityString', () => {
1215
const fixtures = [
@@ -86,7 +89,7 @@ describe('getListTable', () => {
8689
const pasteExpiryDate = '0';
8790
const pasteFormat = 'text';
8891

89-
const xml = getXml(
92+
const xml = getPasteListXml(
9093
pasteKey,
9194
pasteName,
9295
pasteVisibility,
@@ -95,7 +98,7 @@ describe('getListTable', () => {
9598
);
9699

97100
expect(getListTable(xml)).toEqual([
98-
[...TABLE_HEADERS],
101+
[...LIST_TABLE_HEADERS],
99102
[pasteKey, pasteName, 'unlisted', 'Never', pasteFormat],
100103
]);
101104
});
@@ -113,14 +116,14 @@ describe('getListTable', () => {
113116
const pasteExpiryDate2 = '1640992515';
114117
const pasteFormat2 = 'javascript';
115118

116-
const xml = `${getXml(
119+
const xml = `${getPasteListXml(
117120
pasteKey,
118121
pasteName,
119122
pasteVisibility,
120123
pasteExpiryDate,
121124
pasteFormat
122125
)}
123-
${getXml(
126+
${getPasteListXml(
124127
pasteKey2,
125128
pasteName2,
126129
pasteVisibility2,
@@ -129,9 +132,53 @@ describe('getListTable', () => {
129132
)}`;
130133

131134
expect(getListTable(xml)).toEqual([
132-
[...TABLE_HEADERS],
135+
[...LIST_TABLE_HEADERS],
133136
[pasteKey, pasteName, 'unlisted', 'Never', pasteFormat],
134137
[pasteKey2, pasteName2, 'public', '01.01.2022 00:15', pasteFormat2],
135138
]);
136139
});
137140
});
141+
142+
describe('mapAccountPremium', () => {
143+
it('should return free for 0', () => {
144+
expect(mapAccountPremium(0)).toBe('free');
145+
});
146+
147+
it('should return premium for 1', () => {
148+
expect(mapAccountPremium(1)).toBe('premium');
149+
});
150+
});
151+
152+
describe('mapAccountVisibility', () => {
153+
it('should return public for 0', () => {
154+
expect(mapAccountVisibility(0)).toBe('public');
155+
});
156+
157+
it('should return unlisted for 1', () => {
158+
expect(mapAccountVisibility(1)).toBe('unlisted');
159+
});
160+
161+
it('should return private for 2', () => {
162+
expect(mapAccountVisibility(2)).toBe('private');
163+
});
164+
165+
it('should return error for something else', () => {
166+
expect(mapAccountVisibility(3)).toBe('error, could not get from api');
167+
});
168+
});
169+
170+
describe('getUserData', () => {
171+
it('should return table with mapped data', () => {
172+
const userName = 'test user';
173+
const privacy = '0';
174+
const email = '[email protected]';
175+
const premium = '1';
176+
177+
const xml = getUserXml(userName, privacy, email, premium);
178+
179+
expect(getUserData(xml)).toEqual([
180+
[...USER_TABLE_HEADERS],
181+
[userName, 'public', email, 'premium'],
182+
]);
183+
});
184+
});

0 commit comments

Comments
 (0)