Skip to content

Commit 9863a68

Browse files
committed
get articles testing
1 parent eaa7bd5 commit 9863a68

File tree

9 files changed

+182
-104
lines changed

9 files changed

+182
-104
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ node_modules/
22
dist/
33
.clasp.json
44
RestDocs
5-
*.txt
5+
*.txt
6+
src/server/config.js

appsscript.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
2-
"timeZone": "Asia/Calcutta",
2+
"timeZone": "America/Indiana/Indianapolis",
33
"dependencies": {
44
"enabledAdvancedServices": [],
55
"libraries": []
66
},
77
"webapp": {
8-
"access": "ANYONE",
9-
"executeAs": "USER_ACCESSING"
8+
"access": "ANYONE_ANONYMOUS",
9+
"executeAs": "USER_DEPLOYING"
1010
},
1111
"exceptionLogging": "STACKDRIVER",
1212
"oauthScopes": [

src/server/articles/index.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,40 @@
1+
import config from '../config';
2+
import { addHeadings } from '../utils';
3+
/**
4+
* retrieve full article list, support filter parameters for pagination
5+
* @param {*} e
6+
*/
17
function getArticles(e) {
2-
return e;
8+
// work again
9+
const spreadsheet = SpreadsheetApp.openById(config.SPREADSHEET_ID);
10+
// check if device in attempts or checkins
11+
// check checkins
12+
const wkst = spreadsheet.getSheetByName('articles');
13+
// will need to filter length from e
14+
const rows = wkst
15+
.getDataRange()
16+
// .sort({ column: 2, ascending: false })
17+
.getValues();
18+
const headings = rows[0];
19+
const valueRows = rows.slice(1);
20+
const items = {
21+
articles: addHeadings(valueRows, headings)
22+
};
23+
for (let i = 0; i < items.articles.length; i++) {
24+
try {
25+
items.articles[i].author = JSON.parse(items.articles[i].author);
26+
} catch (error) {}
27+
if (!items.articles[i].favoritesCount) {
28+
items.articles[i].favoritesCount = 0;
29+
items.articles[i].favorited = true;
30+
} else items.articles[i].favorited = false;
31+
if (!items.articles[i].tagList) {
32+
items.articles[i].tagList = [];
33+
}
34+
}
35+
Logger.log(e);
36+
37+
return items;
338
}
439

540
function getArticleFeed(e) {

src/server/auth/index.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ function RegisterUser(e) {
1313
return e;
1414
}
1515

16-
function GetProfile(e) {
16+
function GetCurrentProfile(e) {
1717
return e;
1818
}
19-
export default { LoginUser, UpdateProfile, RegisterUser, GetProfile };
19+
20+
function GetUserProfile(e) {
21+
return e;
22+
}
23+
export default { LoginUser, UpdateProfile, RegisterUser, GetCurrentProfile, GetUserProfile };

src/server/config.template.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
var config = {
2+
SPREADSHEET_ID: 'xxxx-xxx',
3+
}
4+
5+
export default config

src/server/mock.js

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1-
const useMock = false;
1+
// paste this in to the live ide to enable
2+
// var useMock = true;
23
const mock = {
3-
postMethod: true,
4+
postMethod: false,
45
eGet: {
5-
parameter: {
6-
key: 'asdf'
6+
"parameter": {
7+
"method": "/api/articles/"
78
},
8-
contextPath: '',
9-
contentLength: -1,
10-
queryString: 'key=asdf',
11-
parameters: {
12-
key: ['asdf']
9+
"contextPath": "",
10+
"contentLength": -1,
11+
"queryString": "method=/api/articles",
12+
"parameters": {
13+
"method": [
14+
"/api/articles"
15+
]
1316
}
1417
},
1518
ePost: {
@@ -38,4 +41,4 @@ const mock = {
3841
}
3942
};
4043

41-
export { useMock, mock };
44+
export { mock };

src/server/utils.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,16 @@ const expBackoff = func => {
1919

2020
const hasCpuTime = () => !(Date.now() - START_TIME > ONE_MINUTE * 4);
2121

22-
export { expBackoff, hasCpuTime };
22+
function addHeadings(posts, headings) {
23+
return posts.map(function(postAsArray) {
24+
const postAsObj = {};
25+
26+
headings.forEach(function(heading, i) {
27+
postAsObj[heading] = postAsArray[i];
28+
});
29+
30+
return postAsObj;
31+
});
32+
}
33+
34+
export { expBackoff, hasCpuTime, addHeadings };

src/server/webapp.js

Lines changed: 99 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
import { useMock, mock } from './mock';
1+
import { mock } from './mock';
22
import ArticleService from './articles';
33
import AuthService from './auth';
44

5+
/**
6+
* match response here https://github.com/gothinkster/realworld/tree/master/api
7+
* @param {*} result
8+
*/
59
function buildSuccessResponse(result) {
6-
const output = JSON.stringify({
7-
status: 'success',
8-
data: result
9-
});
10+
const output = JSON.stringify(result);
1011

1112
return ContentService.createTextOutput(output).setMimeType(ContentService.MimeType.JAVASCRIPT);
1213
}
1314

1415
function buildErrorResponse(message, code) {
1516
const output = JSON.stringify({
16-
status: 'error',
17-
code,
17+
errors: message,
1818
message
1919
});
2020

@@ -26,7 +26,7 @@ const doPost = e => {
2626
// return buildErrorResponse('not authorized', 403);
2727
// }
2828
const request = JSON.parse(JSON.stringify(e));
29-
if (!e.parameter.method) {
29+
if (!request.parameter.method) {
3030
return buildErrorResponse('Post method query parameter missing.', 404);
3131
}
3232
if (request.postData.type === 'application/json') {
@@ -54,102 +54,120 @@ const doPost = e => {
5454
return buildSuccessResponse(response);
5555
case '/api/tags':
5656
return buildSuccessResponse(request);
57-
case e.parameter.method.indexOf('/api/profiles/') !== -1 &&
58-
e.parameter.method.indexOf('/follow') !== -1:
59-
// POST /api/profiles/:username/follow
60-
// DELETE /api/profiles/:username/follow
61-
// support unfollow as well with same method
62-
response = ArticleService.FollowProfile(request);
63-
return buildSuccessResponse(response);
64-
case e.parameter.method.indexOf('/api/articles/') !== -1 &&
65-
e.parameter.method.indexOf('/comments/') !== -1:
66-
// DELETE /api/articles/:slug/comments/:id
67-
response = ArticleService.DeleteArticleComment(request);
68-
return buildSuccessResponse(response);
69-
case e.parameter.method.indexOf('/api/articles/') !== -1 &&
70-
e.parameter.method.indexOf('/comments') !== -1:
71-
// POST /api/articles/:slug/comments
72-
response = ArticleService.CreateArticleComment(request);
73-
return buildSuccessResponse(response);
74-
case e.parameter.method.indexOf('/api/articles/') !== -1 &&
75-
e.parameter.method.indexOf('/favorite') !== -1:
76-
// POST /api/articles/:slug/favorite
77-
// DELETE /api/articles/:slug/favorite
78-
response = ArticleService.FavoriteArticle(request);
79-
return buildSuccessResponse(response);
80-
case e.parameter.method.indexOf('/api/articles/') !== -1:
81-
// PUT /api/articles/:slug
82-
// DELETE /api/articles/:slug
83-
response = ArticleService.CreateDeleteArticle(request);
84-
return buildSuccessResponse(response);
85-
case e.parameter.method.indexOf('/api/articles') !== -1:
86-
// POST /api/articles
87-
response = ArticleService.UpdateArticle(request);
88-
return buildSuccessResponse(response);
8957
default:
90-
// check dynamic routes here?
91-
// /api/profiles/:username
92-
return buildErrorResponse('Post Method not found', 404);
58+
break;
9359
}
60+
if (
61+
request.parameter.method.indexOf('/api/profiles/') !== -1 &&
62+
request.parameter.method.indexOf('/follow') !== -1
63+
) {
64+
// POST /api/profiles/:username/follow
65+
// DELETE /api/profiles/:username/follow
66+
// support unfollow as well with same method
67+
response = ArticleService.FollowProfile(request);
68+
return buildSuccessResponse(response);
69+
}
70+
if (
71+
request.parameter.method.indexOf('/api/articles/') !== -1 &&
72+
request.parameter.method.indexOf('/comments/') !== -1
73+
) {
74+
// DELETE /api/articles/:slug/comments/:id
75+
response = ArticleService.DeleteArticleComment(request);
76+
return buildSuccessResponse(response);
77+
}
78+
if (
79+
request.parameter.method.indexOf('/api/articles/') !== -1 &&
80+
request.parameter.method.indexOf('/comments') !== -1
81+
) {
82+
// POST /api/articles/:slug/comments
83+
response = ArticleService.CreateArticleComment(request);
84+
return buildSuccessResponse(response);
85+
}
86+
if (
87+
request.parameter.method.indexOf('/api/articles/') !== -1 &&
88+
request.parameter.method.indexOf('/favorite') !== -1
89+
) {
90+
// POST /api/articles/:slug/favorite
91+
// DELETE /api/articles/:slug/favorite
92+
response = ArticleService.FavoriteArticle(request);
93+
return buildSuccessResponse(response);
94+
}
95+
if (request.parameter.method.indexOf('/api/articles/') !== -1) {
96+
// PUT /api/articles/:slug
97+
// DELETE /api/articles/:slug
98+
response = ArticleService.CreateDeleteArticle(request);
99+
return buildSuccessResponse(response);
100+
}
101+
if (request.parameter.method.indexOf('/api/articles') !== -1) {
102+
// POST /api/articles
103+
response = ArticleService.UpdateArticle(request);
104+
return buildSuccessResponse(response);
105+
}
106+
// check dynamic routes here?
107+
// /api/profiles/:username
108+
return buildErrorResponse('Post Method not found', 404);
94109
};
95-
96110
const doGet = e => {
97-
let request = JSON.parse(JSON.stringify(e));
111+
let request = null;
112+
try {
113+
request = JSON.parse(JSON.stringify(e));
114+
} catch (error) {
115+
Logger.log('Debugging function directly.');
116+
}
117+
98118
// makes debugging online easier without deploying a new version
99-
if (useMock) {
119+
/* global useMock */
120+
if (typeof useMock !== 'undefined' && useMock) {
100121
if (mock.postMethod) return doPost(mock.ePost);
101122
request = mock.eGet;
123+
// return buildSuccessResponse(request);
102124
}
103-
if (!e.parameter.method) {
125+
if (!request) {
126+
return buildErrorResponse('GET url is empty.', 404);
127+
}
128+
if (!request.parameter.method) {
104129
return buildErrorResponse('GET method query parameter missing.', 404);
105130
}
106131
let response = null;
107132
// route by method
108-
switch (e.parameter.method) {
133+
switch (request.parameter.method) {
109134
case '/api/user':
110-
response = AuthService.GetProfile(request);
135+
response = AuthService.GetCurrentProfile(request);
111136
return buildSuccessResponse(response);
112137
case '/api/articles':
113-
response = ArticleService.UpdateArticle(request);
138+
response = ArticleService.getArticle(request);
114139
return buildSuccessResponse(response);
115140
case '/api/articles/feed':
116-
response = ArticleService.UpdateArticle(request);
141+
response = ArticleService.getArticleFeed(request);
117142
return buildSuccessResponse(response);
118143
case '/api/tags':
119144
response = ArticleService.UpdateArticle(request);
120145
return buildSuccessResponse(response);
121-
case e.parameter.method.indexOf('/api/profiles/') !== -1:
122-
// /api/profiles/:username
123-
response = ArticleService.UpdateArticle(request);
124-
return buildSuccessResponse(response);
125-
case e.parameter.method.indexOf('/api/articles/') !== -1 &&
126-
e.parameter.method.indexOf('/comments') !== -1:
127-
// GET /api/articles/:slug/comments
128-
response = ArticleService.UpdateArticle(request);
129-
return buildSuccessResponse(response);
130-
case e.parameter.method.indexOf('/api/articles/') !== -1:
131-
// GET /api/articles/:slug
132-
response = ArticleService.UpdateArticle(request);
133-
return buildSuccessResponse(response);
134146
default:
135-
// check dynamic routes here?
136-
// /api/profiles/:username
137-
return buildErrorResponse('GET Method not found', 404);
147+
break;
148+
}
149+
if (request.parameter.method.indexOf('/api/profiles/') !== -1) {
150+
// /api/profiles/:username
151+
response = AuthService.GetUserProfile(request);
152+
return buildSuccessResponse(response);
153+
}
154+
if (
155+
request.parameter.method.indexOf('/api/articles/') !== -1 &&
156+
request.parameter.method.indexOf('/comments') !== -1
157+
) {
158+
// GET /api/articles/:slug/comments
159+
response = ArticleService.getArticleComments(request);
160+
return buildSuccessResponse(response);
138161
}
162+
if (request.parameter.method.indexOf('/api/articles/') !== -1) {
163+
// GET /api/articles/:slug
164+
response = ArticleService.getArticles(request);
165+
return buildSuccessResponse(response);
166+
}
167+
// default:
168+
// check dynamic routes here?
169+
// /api/profiles/:username
170+
return buildErrorResponse(`GET Method not found:${request.parameter.method}`, 404);
139171
};
140172

141-
/*
142-
function addHeadings(posts, headings) {
143-
return posts.map(function(postAsArray) {
144-
const postAsObj = {};
145-
146-
headings.forEach(function(heading, i) {
147-
postAsObj[heading] = postAsArray[i];
148-
});
149-
150-
return postAsObj;
151-
});
152-
}
153-
*/
154-
155173
export { doGet, doPost };

webpack.config.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,11 @@ module.exports = {
7979
plugins: [
8080
new CleanWebpackPlugin(),
8181
new CopyWebpackPlugin([
82-
{
83-
from: `${src}/**/*.html`,
84-
flatten: true,
85-
to: destination
86-
},
82+
// {
83+
// from: `${src}/**/*.html`,
84+
// flatten: true,
85+
// to: destination
86+
// },
8787
{
8888
from: `${src}/../appsscript.json`,
8989
to: destination

0 commit comments

Comments
 (0)