Skip to content

Commit 9e435fc

Browse files
author
Esteban Uscanga
committed
Removing config from Picasa, config is injected
only by need
1 parent 1aca192 commit 9e435fc

8 files changed

+128
-145
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const config = {
2525
clientSecret : 'yourClientSecret'
2626
}
2727

28-
const picasa = new Picasa(config)
28+
const picasa = new Picasa()
2929
```
3030

3131
API

example/access_token.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ const code = '4/D7lZJ3L24ugIbgga_82j3JUyKdMVpXppkH3-XeMAE90'
88

99
const picasa = new Picasa(config)
1010

11-
picasa.getAccessToken(code, (error, accessToken) => {
11+
picasa.getAccessToken(config, code, (error, accessToken) => {
1212
console.log(error, accessToken)
1313
})

example/auth_url.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ const Picasa = require('../.')
44
const config = require('./config')
55

66
// First stept
7-
const picasa = new Picasa(config)
7+
const picasa = new Picasa()
88

9-
console.log(picasa.getAuthURL())
9+
console.log(picasa.getAuthURL(config))

example/photos.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
'use strict'
22

33
const Picasa = require('../.')
4-
const config = require('./config')
54

65
// Third step
76
const accessToken = 'ya29.ZAIXMKYXkuw_g_1BBSWfesb5YDi5JVA343G_0oH1qtjC5A6FUdsNBR6l8VOeGyUwH9QmbIc'
87

9-
const picasa = new Picasa(config)
8+
const picasa = new Picasa()
109

1110
picasa.getPhotos(accessToken, null, (error, photos) => {
1211
console.log(error, photos)

src/picasa.js

+56-34
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,15 @@
22

33
const querystring = require('querystring')
44

5-
const request = require('./request')
5+
const executeRequest = require('./request')
66

7-
const userAuthenticationEndpoint = 'https://accounts.google.com/o/oauth2/auth'
8-
const googleScope = 'https://picasaweb.google.com/data/'
9-
const googleAPIhost = 'https://www.googleapis.com'
10-
const googleAPIPath = '/oauth2/v3/token'
7+
const GOOGLE_AUTH_ENDPOINT = 'https://accounts.google.com/o/oauth2/auth'
8+
const GOOGLE_SCOPE = 'https://picasaweb.google.com/data/'
9+
const GOOGLE_API_HOST = 'https://www.googleapis.com'
10+
const GOOGLE_API_PATH = '/oauth2/v3/token'
1111

12-
function Picasa (config) {
13-
this.clientId = config.clientId
14-
this.redirectURI = config.redirectURI
15-
this.clientSecret = config.clientSecret
16-
17-
this.executeRequest = request.executeRequest
18-
this.picasaRequest = request.picasaRequest
12+
function Picasa () {
13+
this.executeRequest = executeRequest
1914
}
2015

2116
Picasa.prototype.getPhotos = getPhotos
@@ -24,7 +19,9 @@ Picasa.prototype.getAuthURL = getAuthURL
2419
Picasa.prototype.getAccessToken = getAccessToken
2520

2621
function getPhotos (accessToken, options, callback) {
27-
this.picasaRequest(accessToken, 'get', 'photo', options, (error, body) => {
22+
const requestOptions = buildPicasaRequestOptions(accessToken, 'photo', options)
23+
24+
this.executeRequest('get', requestOptions, (error, body) => {
2825
if (error) return callback(error)
2926

3027
const photoSchema = {
@@ -60,43 +57,32 @@ function getPhotos (accessToken, options, callback) {
6057
})
6158
}
6259

63-
function checkParam (param) {
64-
if (!param) return ''
65-
if (isValidType(param)) return param
66-
else if (isValidType(param['$t'])) return param['$t']
67-
else return param
68-
}
69-
70-
function isValidType (value) {
71-
return typeof value === 'string' || typeof value === 'number'
72-
}
73-
74-
function getAuthURL () {
60+
function getAuthURL (config) {
7561
const authenticationParams = {
7662
access_type : 'offline',
77-
scope : googleScope,
63+
scope : GOOGLE_SCOPE,
7864
response_type : 'code',
79-
client_id : this.clientId,
80-
redirect_uri : this.redirectURI
65+
client_id : config.clientId,
66+
redirect_uri : config.redirectURI
8167
}
8268

8369
const authenticationQuery = querystring.stringify(authenticationParams)
8470

85-
return `${userAuthenticationEndpoint}?${authenticationQuery}`
71+
return `${GOOGLE_AUTH_ENDPOINT}?${authenticationQuery}`
8672
}
8773

88-
function getAccessToken (code, callback) {
74+
function getAccessToken (config, code, callback) {
8975
const accessTokenParams = {
9076
grant_type : 'authorization_code',
9177
code : code,
92-
redirect_uri : this.redirectURI,
93-
client_id : this.clientId,
94-
client_secret : this.clientSecret
78+
redirect_uri : config.redirectURI,
79+
client_id : config.clientId,
80+
client_secret : config.clientSecret
9581
}
9682

9783
const accessTokenQuery = querystring.stringify(accessTokenParams)
9884
const options = {
99-
url : `${googleAPIhost}${googleAPIPath}?${accessTokenQuery}`
85+
url : `${GOOGLE_API_HOST}${GOOGLE_API_PATH}?${accessTokenQuery}`
10086
}
10187

10288
this.executeRequest('post', options, (error, body) => {
@@ -106,4 +92,40 @@ function getAccessToken (code, callback) {
10692
})
10793
}
10894

95+
function buildPicasaRequestOptions (accessToken, kind, options) {
96+
const host = 'https://picasaweb.google.com'
97+
const path = '/data/feed/api/user/default'
98+
const fetchKind = 'json'
99+
100+
const accessTokenParams = {
101+
alt : fetchKind,
102+
kind : kind,
103+
access_token : accessToken
104+
}
105+
106+
options = options || {}
107+
108+
if (options.maxResults) accessTokenParams['max-results'] = options.maxResults
109+
110+
const accessTokenQuery = querystring.stringify(accessTokenParams)
111+
112+
return {
113+
url : `${host}${path}?${accessTokenQuery}`,
114+
headers: {
115+
'GData-Version': '2'
116+
}
117+
}
118+
}
119+
120+
function checkParam (param) {
121+
if (param === undefined) return ''
122+
else if (isValidType(param)) return param
123+
else if (isValidType(param['$t'])) return param['$t']
124+
else return param
125+
}
126+
127+
function isValidType (value) {
128+
return typeof value === 'string' || typeof value === 'number'
129+
}
130+
109131
module.exports = Picasa

src/picasa.test.js

+65-46
Original file line numberDiff line numberDiff line change
@@ -18,91 +18,110 @@ describe('Picasa', () => {
1818
clientSecret : 'client_secretABC'
1919
}
2020

21-
beforeEach(() => {
22-
picasa = new Picasa(config)
23-
})
21+
beforeEach(() => picasa = new Picasa())
2422

2523
describe('getPhotos', () => {
2624
describe('on success', () => {
27-
beforeEach(() => {
28-
const body = {
29-
"feed":{
30-
"entry":[
31-
{
32-
"id":{
33-
"$t":"https://picasaweb.google.com/data/entry/user/11111/albumid/1111/photoid/11111"
34-
},
35-
"published":{
36-
"$t":"2015-11-28T07:13:31.000Z"
37-
},
38-
"updated":{
39-
"$t":"2015-11-28T07:22:35.478Z"
40-
},
41-
"app$edited":{
42-
"$t":"2015-11-28T07:22:35.478Z"
43-
},
44-
"title":{
45-
"$t":"IMG_0327.JPG"
46-
},
47-
"summary":{
48-
"$t":""
49-
},
50-
"content":{
51-
"type":"image/jpeg",
52-
"src":"https://lh3.googleusercontent.com/-1111111/1111/11111/1111/IMG_0327.JPG"
53-
}
25+
const fakeSuccessBody = {
26+
"feed":{
27+
"entry":[
28+
{
29+
"id":{
30+
"$t":"https://picasaweb.google.com/data/entry/user/11111/albumid/1111/photoid/11111"
31+
},
32+
"published":{
33+
"$t":"2015-11-28T07:13:31.000Z"
34+
},
35+
"updated":{
36+
"$t":"2015-11-28T07:22:35.478Z"
37+
},
38+
"app$edited":{
39+
"$t":"2015-11-28T07:22:35.478Z"
40+
},
41+
"title":{
42+
"$t":"IMG_0327.JPG"
43+
},
44+
"summary":{
45+
"$t":""
46+
},
47+
"content":{
48+
"type":"image/jpeg",
49+
"src":"https://lh3.googleusercontent.com/-1111111/1111/11111/1111/IMG_0327.JPG"
5450
}
55-
]
56-
}
51+
}
52+
]
5753
}
54+
}
5855

59-
stub = sinon.stub(picasa, 'picasaRequest')
60-
stub.callsArgWithAsync(4, null, body)
61-
})
56+
let photos
6257

63-
afterEach(() => stub.restore())
58+
beforeEach((done) => {
59+
stub = sinon.stub(picasa, 'executeRequest')
60+
stub.callsArgWithAsync(2, null, fakeSuccessBody)
6461

65-
it('returns an array of photos', (done) => {
6662
const accessToken = 'ya29.OwJqqa1Y2tivkkCWWvA8vt5ltKsdf9cDQ5IRNrTbIt-mcfr5xNj4dQu41K6hZa7lX9O-gw'
6763

68-
picasa.getPhotos(accessToken, { maxResults : 1 }, (error, photos) => {
64+
picasa.getPhotos(accessToken, { maxResults : 1 }, (error, photosResponse) => {
6965
expect(error).to.be.equals(null)
66+
photos = photosResponse
7067

68+
done()
69+
})
70+
})
7171

72-
expect(photos[0].title).to.be.equals('IMG_0327.JPG')
73-
expect(photos[0].content.src).to.contain('IMG_0327.JPG')
74-
expect(photos[0].content.type).to.be.equals('image/jpeg')
72+
afterEach(() => stub.restore())
7573

76-
done()
74+
it('returns an array of photos', () => {
75+
expect(photos).to.be.an('Array')
76+
})
77+
78+
it('returns a photo with its props', () => {
79+
expect(photos[0].title).to.be.equals('IMG_0327.JPG')
80+
expect(photos[0].content.src).to.contain('IMG_0327.JPG')
81+
expect(photos[0].content.type).to.be.equals('image/jpeg')
82+
})
83+
84+
it('should make get request', () => {
85+
const firstArgument = stub.args[0][0]
86+
87+
expect(firstArgument).to.be.eql('get')
88+
})
89+
90+
it('should add header and prepared URL to request', () => {
91+
const secondArgument = stub.args[0][1]
92+
93+
expect(secondArgument).to.be.eql({
94+
headers : { 'GData-Version': "2" },
95+
url : "https://picasaweb.google.com/data/feed/api/user/default?alt=json&kind=photo&access_token=ya29.OwJqqa1Y2tivkkCWWvA8vt5ltKsdf9cDQ5IRNrTbIt-mcfr5xNj4dQu41K6hZa7lX9O-gw&max-results=1"
7796
})
7897
})
7998
})
8099
})
81100

82101
describe('getAuthURL', () => {
83102
it('returns valid URI', () => {
84-
expect(picasa.getAuthURL())
103+
expect(picasa.getAuthURL(config))
85104
.to.be.equals('https://accounts.google.com/o/oauth2/auth?access_type=offline&scope=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2F&response_type=code&client_id=apps.google.com&redirect_uri=http%3A%2F%2Flocalhost')
86105
})
87106
})
88107

89108
describe('getAccessToken', () => {
90109
beforeEach(() => {
91-
const body = {
110+
const fakeBody = {
92111
access_token : 'ya29.KwLDeXsw1jNAavZ8jEMFgikhDg_CnUX1oMr5RQUyeqTBf229YV4HzhhXvRgBBvFGqTqxdw',
93112
token_type : 'Bearer',
94113
expires_in : 3580
95114
}
96115

97116
stub = sinon.stub(picasa, 'executeRequest')
98117

99-
stub.callsArgWithAsync(2, null, body)
118+
stub.callsArgWithAsync(2, null, fakeBody)
100119
})
101120

102121
afterEach(() => stub.restore())
103122

104123
it('returns access token response', (done) => {
105-
picasa.getAccessToken('4/DxoCTw8Rf3tQAAW94h6lK7ioEjnu6K8kEqVZ0d-cRA8', (error, accessToken) => {
124+
picasa.getAccessToken(config, '4/DxoCTw8Rf3tQAAW94h6lK7ioEjnu6K8kEqVZ0d-cRA8', (error, accessToken) => {
106125
expect(stub).to.have.been.calledWith('post', { url : 'https://www.googleapis.com/oauth2/v3/token?grant_type=authorization_code&code=4%2FDxoCTw8Rf3tQAAW94h6lK7ioEjnu6K8kEqVZ0d-cRA8&redirect_uri=http%3A%2F%2Flocalhost&client_id=apps.google.com&client_secret=client_secretABC' })
107126

108127
expect(error).to.be.equal(null)

src/request.js

+1-30
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,6 @@
33
const querystring = require('querystring')
44
let request = require('request')
55

6-
function picasaRequest (accessToken, method, kind, options, callback) {
7-
const host = 'https://picasaweb.google.com'
8-
const path = '/data/feed/api/user/default'
9-
const fetchKind = 'json'
10-
11-
const accessTokenParams = {
12-
alt : fetchKind,
13-
kind : kind,
14-
access_token : accessToken
15-
}
16-
17-
options = options || {}
18-
19-
if (options.maxResults) accessTokenParams['max-results'] = options.maxResults
20-
21-
const accessTokenQuery = querystring.stringify(accessTokenParams)
22-
const requestOptions = {
23-
url : `${host}${path}?${accessTokenQuery}`,
24-
headers: {
25-
'GData-Version': '2'
26-
}
27-
}
28-
29-
executeRequest(method, requestOptions, callback)
30-
}
31-
326
function executeRequest (method, requestOptions, callback) {
337
request[method](requestOptions, (error, response, body) => {
348
if (error) return callback(error)
@@ -51,7 +25,4 @@ function executeRequest (method, requestOptions, callback) {
5125
})
5226
}
5327

54-
module.exports = {
55-
picasaRequest : picasaRequest,
56-
executeRequest : executeRequest
57-
}
28+
module.exports = executeRequest

0 commit comments

Comments
 (0)