Skip to content

Commit 4770012

Browse files
authored
Merge pull request #25 from bflorian/dynamic-pages
Added support for async calls in pages to return dynamic content
2 parents 4e2e16e + e5826c5 commit 4770012

File tree

5 files changed

+74
-71
lines changed

5 files changed

+74
-71
lines changed

lib/pages/page.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module.exports = class Page {
1919
this._defaultRequired = true
2020
}
2121

22-
section(name, closure) {
22+
async section(name, closure) {
2323
let sec
2424
let callable = closure
2525
if (typeof name === 'string') {
@@ -31,7 +31,7 @@ module.exports = class Page {
3131

3232
this._sections.push(sec)
3333
if (callable) {
34-
callable(sec)
34+
await callable(sec)
3535
}
3636

3737
return this

lib/smart-app.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,9 @@ module.exports = class SmartApp {
228228
this._handleCallback(request.body, responders.httpResponder(response, this._log))
229229
}
230230

231-
handleMockCallback(body) {
231+
async handleMockCallback(body) {
232232
const responder = responders.mockResponder(this._log)
233-
this._handleCallback(body, responder)
233+
await this._handleCallback(body, responder)
234234
return responder.response
235235
}
236236

@@ -293,8 +293,9 @@ module.exports = class SmartApp {
293293
const pageHandler = this._pages[pageId]
294294
if (pageHandler) {
295295
const page = this._localizationEnabled ? new Page(pageId, context.locale) : new Page(pageId)
296-
pageHandler(context, page, configurationData)
297-
responder.respond({statusCode: 200, configurationData: {page: page.toJson()}})
296+
Promise.resolve(pageHandler(context, page, configurationData)).then(() => {
297+
responder.respond({statusCode: 200, configurationData: {page: page.toJson()}})
298+
})
298299
} else {
299300
throw new Error(`Page '${configurationData.pageId}' not found`)
300301
}

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@smartthings/smartapp",
3-
"version": "1.0.1",
3+
"version": "1.0.2",
44
"description": "NodeJS SDK for SmartApps",
55
"displayName": "SmartThings SmartApp SDK for NodeJS",
66
"author": "SmartThings",

test/smartapp-page-spec.js

Lines changed: 65 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ describe('smartapp-page-spec', () => {
2020
})
2121
})
2222

23-
const initResponse = app.handleMockCallback({
23+
// Initialize configuration callback
24+
app.handleMockCallback({
2425
lifecycle: 'CONFIGURATION',
2526
executionId: 'e6903fe6-f88f-da69-4c12-e2802606ccbc',
2627
locale: 'en',
@@ -38,9 +39,19 @@ describe('smartapp-page-spec', () => {
3839
config: {}
3940
},
4041
settings: {}
42+
}).then(initResponse => {
43+
const expectedInitResponse = {initialize: {
44+
id: 'xxx',
45+
firstPageId: 'eaMainPage',
46+
permissions: [],
47+
disableCustomDisplayName: false,
48+
disableRemoveApp: false
49+
}}
50+
51+
assert.deepStrictEqual(initResponse.configurationData, expectedInitResponse)
4152
})
4253

43-
const pageResponse = app.handleMockCallback({
54+
app.handleMockCallback({
4455
lifecycle: 'CONFIGURATION',
4556
executionId: 'abcf6e72-60f4-1f27-341b-449ad9e2192e',
4657
locale: 'en',
@@ -58,68 +69,59 @@ describe('smartapp-page-spec', () => {
5869
config: {}
5970
},
6071
settings: {}
61-
})
62-
63-
const expectedInitResponse = {initialize: {
64-
id: 'xxx',
65-
firstPageId: 'eaMainPage',
66-
permissions: [],
67-
disableCustomDisplayName: false,
68-
disableRemoveApp: false
69-
}}
70-
71-
const expectedPageResponse = {
72-
page: {
73-
name: 'pages.eaMainPage.name',
74-
complete: true,
75-
pageId: 'eaMainPage',
76-
nextPageId: null,
77-
previousPageId: null,
78-
sections: [
79-
{
80-
name: 'whenDoorOpensAndCloses',
81-
settings: [
82-
{
83-
id: 'contactSensor',
84-
name: 'pages.eaMainPage.settings.contactSensor.name',
85-
required: true,
86-
type: 'DEVICE',
87-
description: 'Tap to set',
88-
multiple: false,
89-
capabilities: [
90-
'contactSensor'
91-
],
92-
permissions: [
93-
'r'
94-
]
95-
}
96-
]
97-
},
98-
{
99-
name: 'turnLightsOnAndOff',
100-
settings: [
101-
{
102-
id: 'lights',
103-
name: 'pages.eaMainPage.settings.lights.name',
104-
required: true,
105-
type: 'DEVICE',
106-
description: 'Tap to set',
107-
multiple: true,
108-
capabilities: [
109-
'switch'
110-
],
111-
permissions: [
112-
'r',
113-
'x'
114-
]
115-
}
116-
]
117-
}
118-
]
72+
}).then(pageResponse => {
73+
const expectedPageResponse = {
74+
page: {
75+
name: 'pages.eaMainPage.name',
76+
complete: true,
77+
pageId: 'eaMainPage',
78+
nextPageId: null,
79+
previousPageId: null,
80+
sections: [
81+
{
82+
name: 'whenDoorOpensAndCloses',
83+
settings: [
84+
{
85+
id: 'contactSensor',
86+
name: 'pages.eaMainPage.settings.contactSensor.name',
87+
required: true,
88+
type: 'DEVICE',
89+
description: 'Tap to set',
90+
multiple: false,
91+
capabilities: [
92+
'contactSensor'
93+
],
94+
permissions: [
95+
'r'
96+
]
97+
}
98+
]
99+
},
100+
{
101+
name: 'turnLightsOnAndOff',
102+
settings: [
103+
{
104+
id: 'lights',
105+
name: 'pages.eaMainPage.settings.lights.name',
106+
required: true,
107+
type: 'DEVICE',
108+
description: 'Tap to set',
109+
multiple: true,
110+
capabilities: [
111+
'switch'
112+
],
113+
permissions: [
114+
'r',
115+
'x'
116+
]
117+
}
118+
]
119+
}
120+
]
121+
}
119122
}
120-
}
121-
assert.deepStrictEqual(initResponse.configurationData, expectedInitResponse)
122-
assert.deepStrictEqual(pageResponse.configurationData, expectedPageResponse)
123+
assert.deepStrictEqual(pageResponse.configurationData, expectedPageResponse)
124+
})
123125
})
124126

125127
it('should configure event logger', () => {

0 commit comments

Comments
 (0)