eitri-cli 1.0.2

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.
Files changed (122) hide show
  1. package/README.md +54 -0
  2. package/bitbucket-pipelines.toBeChanged.yml +64 -0
  3. package/boilerplate/mini-app-cafe-madeira.zip +0 -0
  4. package/check-version.js +12 -0
  5. package/config/default-eitri.js +1 -0
  6. package/config/dev.js +91 -0
  7. package/config/k8s-eitri.js +92 -0
  8. package/config/loc-eitri.js +92 -0
  9. package/config/prod-eitri.js +92 -0
  10. package/config/test-eitri.js +2 -0
  11. package/index-eitri.js +6 -0
  12. package/index.js +182 -0
  13. package/install-dev.bat +1 -0
  14. package/install-dev.sh +1 -0
  15. package/jest.config.js +6 -0
  16. package/jsconfig.json +9 -0
  17. package/package.json +80 -0
  18. package/publisher.js +53 -0
  19. package/src/cmd/clean.js +179 -0
  20. package/src/cmd/create.js +281 -0
  21. package/src/cmd/credentials.js +105 -0
  22. package/src/cmd/invite.js +87 -0
  23. package/src/cmd/list.js +36 -0
  24. package/src/cmd/login.js +51 -0
  25. package/src/cmd/manage-env.js +129 -0
  26. package/src/cmd/open-share.js +6 -0
  27. package/src/cmd/order-details.js +6 -0
  28. package/src/cmd/push-version.js +182 -0
  29. package/src/cmd/show-message-if-outdated-package.js +32 -0
  30. package/src/cmd/signup.js +69 -0
  31. package/src/cmd/start.js +171 -0
  32. package/src/cmd/tail-logs.js +26 -0
  33. package/src/cmd/test-initialization-params.js +6 -0
  34. package/src/cmd/validate.js +170 -0
  35. package/src/cmd/version.js +29 -0
  36. package/src/enum/WatcherOpts.js +3 -0
  37. package/src/enum/target.js +6 -0
  38. package/src/helpers/request-listener-helper.js +55 -0
  39. package/src/model/Payload.js +45 -0
  40. package/src/model/Target.js +76 -0
  41. package/src/model/User.js +11 -0
  42. package/src/service/AuthConfig.js +88 -0
  43. package/src/service/BlindGuardian.js +134 -0
  44. package/src/service/CliLogin.js +47 -0
  45. package/src/service/ConfigService.js +16 -0
  46. package/src/service/CredentialsService.js +47 -0
  47. package/src/service/GATrackingStrategy.js +16 -0
  48. package/src/service/HashFolder.js +79 -0
  49. package/src/service/Http.js +234 -0
  50. package/src/service/InviteService.js +45 -0
  51. package/src/service/ManageEnvService.js +10 -0
  52. package/src/service/MiniLog.js +132 -0
  53. package/src/service/QRCodeFactory.js +43 -0
  54. package/src/service/Server.js +239 -0
  55. package/src/service/StarterService.js +31 -0
  56. package/src/service/TagTree.js +101 -0
  57. package/src/service/TargetService.js +97 -0
  58. package/src/service/TrackService.js +11 -0
  59. package/src/service/TrackingEitriAnalytics.js +32 -0
  60. package/src/service/TrackingService.js +183 -0
  61. package/src/service/ValidateResult.js +57 -0
  62. package/src/service/Watcher.js +119 -0
  63. package/src/service/Workspace.js +1069 -0
  64. package/src/service/WorkspaceManager.js +74 -0
  65. package/src/service/factories/DoubtsStarterFactory.js +25 -0
  66. package/src/service/factories/MiniWebAppFactory.js +43 -0
  67. package/src/service/factories/QRCodeStarterFactory.js +78 -0
  68. package/src/service/factories/WebStarterFactory.js +88 -0
  69. package/src/service/factories/WoodCoffeeFactory.js +230 -0
  70. package/src/util/AboutTemplate.jsx +14 -0
  71. package/src/util/UrlUtils.js +12 -0
  72. package/src/util/UserLocalCredential.js +122 -0
  73. package/src/util/error-messages/error-messages.js +24 -0
  74. package/src/util/error-messages/invite/invite-error-messages.js +14 -0
  75. package/src/util/getCliVersion.js +13 -0
  76. package/src/util/getCreateFactory.js +9 -0
  77. package/src/util/ipv4.js +19 -0
  78. package/src/util/manage-env.js +65 -0
  79. package/src/util/open-docs.js +7 -0
  80. package/src/util/os.js +39 -0
  81. package/src/util/server-url.js +15 -0
  82. package/src/util/template-utils.js +21 -0
  83. package/src/view/index.html +19 -0
  84. package/targetMobileStickyness.md +47 -0
  85. package/targetWebStickyness.md +40 -0
  86. package/test/_fixtures/factory.js +30 -0
  87. package/test/_fixtures/miniWebApp/miniapp.conf.js +4 -0
  88. package/test/_fixtures/miniapp.conf.js +5 -0
  89. package/test/_fixtures/server/HelloWorldBackend.js +7 -0
  90. package/test/_fixtures/src/Home.js +5 -0
  91. package/test/_fixtures/src/Home2.js +5 -0
  92. package/test/_fixtures/src/commons/util.js +3 -0
  93. package/test/_fixtures/src/components/TagA.jsx +4 -0
  94. package/test/_fixtures/src/components/TagB.jsx +4 -0
  95. package/test/_fixtures/src/components/TagC.jsx +3 -0
  96. package/test/_fixtures/src/components/TagD.jsx +3 -0
  97. package/test/_fixtures/src/server/foo.js +7 -0
  98. package/test/_fixtures/src/views/AboutTemplate.jsx +14 -0
  99. package/test/_fixtures/woodcoffee/miniapp.conf.js +3 -0
  100. package/test/ame.conf.js +3 -0
  101. package/test/cmd/clean.test.js +66 -0
  102. package/test/cmd/create.test.js +252 -0
  103. package/test/cmd/credentials.test.js +159 -0
  104. package/test/cmd/list.test.js +74 -0
  105. package/test/cmd/manage-env.test.js +168 -0
  106. package/test/cmd/signup.test.js +20 -0
  107. package/test/cmd/start.test.js +5 -0
  108. package/test/miniapp.conf.js +3 -0
  109. package/test/model/Payload.test.js +35 -0
  110. package/test/service/BlindGuardian.test.js +84 -0
  111. package/test/service/CheckAmeConf.test.js +313 -0
  112. package/test/service/Http.test.js +312 -0
  113. package/test/service/InviteService.test.js +117 -0
  114. package/test/service/MiniWebAppFactory.test.js +40 -0
  115. package/test/service/TagTree.test.js +81 -0
  116. package/test/service/TargetService.test.js +48 -0
  117. package/test/service/TrackingService.test.js +105 -0
  118. package/test/service/UserAmeConf.test.js +47 -0
  119. package/test/service/WoodCoffeeFactory.test.js +148 -0
  120. package/test/service/Workspace.test.js +364 -0
  121. package/thinQrCode.md +58 -0
  122. package/v1.5.0.md +3 -0
@@ -0,0 +1,105 @@
1
+ /* eslint-disable no-undef */
2
+ const nock = require('nock')
3
+ const path = require('path')
4
+ const TrackingService = require('../../src/service/TrackingService')
5
+ const { v4: uuidv4 } = require('uuid')
6
+
7
+ describe('TrackingService', () => {
8
+ let workspace, blindGuardian, trackingService
9
+
10
+ beforeEach(() => {
11
+ nock.cleanAll()
12
+ folder2watch = path.resolve(__dirname, '..', '_fixtures')
13
+
14
+ workspace = require('../../src/service/Workspace').workspace
15
+ // workspace.setFolder2Watch(folder2watch)
16
+ workspace.setServerUrl('https://dev.eitri.calindra.com.br')
17
+
18
+ blindGuardian = workspace.blindGuardian
19
+ blindGuardian.getToken = async () => {
20
+ return { accessToken: 'xpto' }
21
+ }
22
+ trackingService = new TrackingService(blindGuardian)
23
+ })
24
+
25
+ it('testa envio de error', async () => {
26
+ let params = []
27
+ nock('https://www.google-analytics.com')
28
+ .get('/collect')
29
+ .query(q => {
30
+ params.push(q)
31
+ return true
32
+ })
33
+ .reply(200, '')
34
+ .persist()
35
+ await trackingService.sendError(new Error('Meu erro'))
36
+ expect(params[0].v).toBe('1')
37
+ expect(params[0].exd).toContain('Meu erro')
38
+ expect(params[0].exd).toContain(path.basename(__filename))
39
+ })
40
+
41
+ it('testa envio de save', async () => {
42
+ let params = []
43
+ nock('https://www.google-analytics.com')
44
+ .get('/collect')
45
+ .query(q => {
46
+ params.push(q)
47
+ return true
48
+ })
49
+ .reply(200, '')
50
+ .persist()
51
+ let event = {
52
+ superClientVersion: '1.2.2',
53
+ componentsVersion: '1.4.5',
54
+ miniAppSlug: 'algum-slug',
55
+ miniAppVersion: '0.1.0',
56
+ timeMs: 3000,
57
+ }
58
+ await trackingService.sendSave(event)
59
+ expect(params[0].v).toBe('1')
60
+ })
61
+
62
+ it('testa envio de publish', async () => {
63
+ let params = []
64
+ nock('https://www.google-analytics.com')
65
+ .get('/collect')
66
+ .query(q => {
67
+ params.push(q)
68
+ return true
69
+ })
70
+ .reply(200, '')
71
+ .persist()
72
+ trackingService._clientId = uuidv4()
73
+ let event = {
74
+ superClientVersion: '1.2.2',
75
+ componentsVersion: '1.4.5',
76
+ miniAppSlug: 'algum-slug',
77
+ miniAppVersion: '0.1.0',
78
+ timeMs: 3000,
79
+ }
80
+ await trackingService.sendPublish(event)
81
+ expect(params[0].v).toBe('1')
82
+ })
83
+
84
+ it('testa envio de build', async () => {
85
+ let params = []
86
+ nock('https://www.google-analytics.com')
87
+ .get('/collect')
88
+ .query(q => {
89
+ params.push(q)
90
+ return true
91
+ })
92
+ .reply(200, '')
93
+ .persist()
94
+ trackingService._clientId = uuidv4()
95
+ let event = {
96
+ superClientVersion: '1.2.2',
97
+ componentsVersion: '1.4.5',
98
+ miniAppSlug: 'algum-slug',
99
+ miniAppVersion: '0.1.0',
100
+ timeMs: 3000,
101
+ }
102
+ await trackingService.sendBuild(event)
103
+ expect(params[0].v).toBe('1')
104
+ })
105
+ })
@@ -0,0 +1,47 @@
1
+ /* eslint-disable no-undef */
2
+
3
+
4
+ const BlindGuardian = require('../../src/service/BlindGuardian')
5
+
6
+ describe('UserAmeConf', () => {
7
+ let blindGuardian
8
+
9
+ beforeEach(() => {
10
+ blindGuardian = new BlindGuardian()
11
+ })
12
+
13
+ it('deve ler arquivo de configuracao do [env].conf na versão antiga', () => {
14
+ blindGuardian.readConf = () => {
15
+ return {
16
+ devUser: 'foo',
17
+ devKey: 'bar',
18
+ }
19
+ }
20
+
21
+ let credential = blindGuardian.readClientCredentials()
22
+ expect(credential.client_id).toEqual('foo')
23
+ expect(credential.client_secret).toEqual('bar')
24
+ })
25
+
26
+ it('deve ler arquivo de configuracao do [env].conf com configuracões distintas para diversos ambientes', () => {
27
+
28
+ blindGuardian.readConf = () => {
29
+ return {
30
+ 'test': {
31
+ 'devUser': 'foo-test',
32
+ 'devKey': 'bar-test'
33
+ },
34
+ 'local': {
35
+ 'devUser': 'foo-local',
36
+ 'devKey': 'bar-local'
37
+ }
38
+ }
39
+ }
40
+
41
+ let credential = blindGuardian.readClientCredentials()
42
+ expect(credential.client_id).toEqual('foo-test')
43
+ expect(credential.client_secret).toEqual('bar-test')
44
+ })
45
+
46
+
47
+ })
@@ -0,0 +1,148 @@
1
+ /* eslint-disable no-undef */
2
+ const fs = require('fs')
3
+ const path = require('path')
4
+
5
+ const WoodCoffeeFactory = require('../../src/service/factories/WoodCoffeeFactory')
6
+ const { after } = require('../../node_modules/cheerio/lib/api/manipulation')
7
+ const { getTarget } = require('../_fixtures/factory')
8
+ const child_process = require('child_process')
9
+
10
+ describe('WoodCoffeeFactory', () => {
11
+ let woodCoffeeFactory
12
+ beforeEach(() => {
13
+ woodCoffeeFactory = new WoodCoffeeFactory()
14
+ })
15
+ describe('.validateFileName(projectName)', () => {
16
+ it('valida o nome do projeto contra caracteres estranhos', async () => {
17
+ let valid = woodCoffeeFactory.validateFileName('../lalala')
18
+ expect(valid).toBe(false)
19
+ })
20
+ it('valida pasta aux da morte do windows', async () => {
21
+ let valid = woodCoffeeFactory.validateFileName('aux')
22
+ expect(valid).toBe(false)
23
+ })
24
+ it('valida um nome ok', async () => {
25
+ let valid = woodCoffeeFactory.validateFileName('meu-projeto')
26
+ expect(valid).toBe(true)
27
+ })
28
+ })
29
+ describe('.writeAmeConf(project, conf, libsName)', () => {
30
+ it('valida se o miniapp.conf.js foi criado corretamente', async () => {
31
+ let conf = {}
32
+ conf['version'] = '0.1.0'
33
+
34
+ let project = {}
35
+ project['projectPath'] = path.resolve(__dirname, '..', '_fixtures', 'woodcoffee')
36
+
37
+ jest.spyOn(woodCoffeeFactory, '_getLatestLibVersion').mockReturnValueOnce('0.0.1')
38
+
39
+ let libsName = ['test_lib_1']
40
+ await woodCoffeeFactory.writeAmeConf(project, conf, libsName)
41
+
42
+ let expectedConf = {
43
+ version: '0.1.0'
44
+ }
45
+
46
+ let expected = `module.exports = ${JSON.stringify(expectedConf, null, 4)}`
47
+
48
+ const data = fs.readFileSync(path.join(project.projectPath, 'miniapp.conf.js'), {
49
+ encoding: 'utf-8',
50
+ flag: 'r'
51
+ })
52
+
53
+ expect(data).toBe(expected)
54
+ })
55
+ })
56
+
57
+ describe('.template(projectName, templateUrl, projectPath)', () => {
58
+ const COMPONENTS_LIBRARY_VERSION_HIGHLIGHTER = '###COMPONENTS_LIBRARY_VERSION_HIGHLIGHTER###'
59
+ const SUPER_APP_CLIENT_VERSION_HIGHLIGHTER = '###SUPER_APP_CLIENT_VERSION_HIGHLIGHTER###'
60
+ const templateFileName = 'AboutTemplate.jsx'
61
+ const aboutTemplatePath = path.join(path.dirname(__dirname), '_fixtures', 'src', 'views', templateFileName)
62
+ const destinyFolder = path.join(path.dirname(__dirname), '_fixtures', 'src', 'views', 'About.jsx')
63
+ let target;
64
+ beforeEach(() => {
65
+ target = getTarget()
66
+ fs.copyFile(aboutTemplatePath, destinyFolder, (error) => {
67
+
68
+ if (error) {
69
+ console.error(`O arquivo [${templateFileName}] não foi copiado para a pasta de destino [${destinyFolder}] \n`, error)
70
+ return
71
+ }
72
+ })
73
+ })
74
+
75
+ afterEach(() => {
76
+ fs.unlink(destinyFolder, (error) => {
77
+ if (error) {
78
+ console.error(`O arquivo [${templateFileName}] não foi deletado do destino [${destinyFolder}] \n`, error)
79
+ return
80
+ }
81
+ })
82
+ })
83
+
84
+ it('deve verificar se as versões das bibliotecas foram atualizadas', async () => {
85
+ const file = await getFile()
86
+ expect(file.includes(COMPONENTS_LIBRARY_VERSION_HIGHLIGHTER) && file.includes(SUPER_APP_CLIENT_VERSION_HIGHLIGHTER)).toBeTruthy()
87
+ const newConf = {
88
+ 'eitri-app-client': '2.26.0',
89
+ 'eitri-app-components': '2.26.0'
90
+ }
91
+ await woodCoffeeFactory.updateAboutJSXFile(destinyFolder, newConf)
92
+
93
+ const updatedFile = await getFile()
94
+ expect(updatedFile.includes('2.26.0') && updatedFile.includes('2.26.0')).toBeTruthy()
95
+ })
96
+
97
+ it('deve lançar um erro quando o About.jsx for baixado sem os marcadores', async () => {
98
+ await updateFile()
99
+ try {
100
+ const result = await woodCoffeeFactory.checkAboutJsx(destinyFolder)
101
+ expect(result).toBe('Caiu aqui tá errado!')
102
+ } catch (error) {
103
+ expect(error.message).toBe('Faltam placeholders para exibicao da versao do components e client')
104
+
105
+ }
106
+ })
107
+
108
+ it('deve usar o arquivo de template ao invés do baixado no github', async () => {
109
+ await updateFile()
110
+ jest.spyOn(woodCoffeeFactory, 'downloadFromGithub').mockResolvedValueOnce(new Promise(resolve => resolve()))
111
+ jest.spyOn(woodCoffeeFactory, '_getLatestLibVersion').mockReturnValueOnce(() => '2.26.0')
112
+ jest.spyOn(child_process, 'execSync').mockReturnValue("2.26.0")
113
+ const projectPath = path.join(path.dirname(__dirname), '_fixtures')
114
+ await woodCoffeeFactory.template('woodcoffee', 'https://template-url', projectPath, target)
115
+ const updatedFile = await getFile()
116
+ expect(updatedFile.includes('2.26.0') && updatedFile.includes('2.26.0')).toBeTruthy()
117
+ })
118
+
119
+ async function updateFile() {
120
+ const contents = await getFile()
121
+ return new Promise((resolve, reject) => {
122
+ const replaced = contents
123
+ .replace(COMPONENTS_LIBRARY_VERSION_HIGHLIGHTER, '2.0.0')
124
+ .replace(SUPER_APP_CLIENT_VERSION_HIGHLIGHTER, '2.8.1')
125
+ fs.writeFile(destinyFolder, replaced, 'utf-8', function (err) {
126
+ if (err) {
127
+ console.log(err)
128
+ reject()
129
+ }
130
+ resolve()
131
+ })
132
+ })
133
+ }
134
+
135
+ function getFile() {
136
+ return new Promise((resolve, reject) => {
137
+ fs.readFile(destinyFolder, 'utf-8', function (err, contents) {
138
+ if (err) {
139
+ console.log(err)
140
+ reject(err)
141
+ }
142
+ resolve(contents)
143
+ })
144
+
145
+ })
146
+ }
147
+ })
148
+ })
@@ -0,0 +1,364 @@
1
+ /* eslint-disable no-undef */
2
+
3
+ const nock = require('nock')
4
+ const path = require('path')
5
+ const url = require('url')
6
+
7
+ describe('Workspace', () => {
8
+ let workspace, folder2watch
9
+ beforeEach(() => {
10
+ nock.cleanAll()
11
+ folder2watch = path.resolve(__dirname, '..', '_fixtures')
12
+
13
+ workspace = require('../../src/service/Workspace').workspace
14
+ workspace.setFolder2Watch(folder2watch)
15
+ workspace.setServerUrl('https://dev.eitri.calindra.com.br')
16
+ workspace.setMiniConf({ version: '0.1.0' })
17
+ workspace.blindGuardian.getToken = async () => {
18
+ return { accessToken: 'xpto' }
19
+ }
20
+ })
21
+
22
+ afterEach(() => {
23
+ nock.cleanAll()
24
+ })
25
+
26
+ describe('.upsert(filePath)', () => {
27
+ it('envia o nome do arquivo para o servidor relativo a pasta do projeto local', (done) => {
28
+ nock('https://dev.eitri.calindra.com.br')
29
+ .post('/workspace/fileupload', (body) => {
30
+ let m = body.match(/\s+\/src\/Home\.js/)
31
+ expect(m).not.toBeNull()
32
+ done()
33
+ return true
34
+ })
35
+ .reply(200, {})
36
+ let filePath = path.resolve(folder2watch, 'src', 'Home.js')
37
+ workspace.upsert(filePath)
38
+ })
39
+ it('envia o arquivo para o servidor', (done) => {
40
+ nock('https://dev.eitri.calindra.com.br')
41
+ .post('/workspace/fileupload', (body) => {
42
+ let m = body.match(/name="file"; filename="Home\.js"/)
43
+ expect(m).not.toBeNull()
44
+ done()
45
+ return true
46
+ })
47
+ .reply(200, {})
48
+ let filePath = path.resolve(folder2watch, 'src', 'Home.js')
49
+ workspace.upsert(filePath)
50
+ })
51
+ it('envia em sequencia', (done) => {
52
+ nock('https://dev.eitri.calindra.com.br')
53
+ .post('/workspace/fileupload')
54
+ .delayBody(1000)
55
+ .reply(200, { request: 1 })
56
+ nock('https://dev.eitri.calindra.com.br')
57
+ .post('/workspace/fileupload')
58
+ .delayBody(100)
59
+ .reply(200, { request: 2 })
60
+ let filePath = path.resolve(folder2watch, 'src', 'Home.js')
61
+ let a = workspace.upsert(filePath)
62
+ let filePath2 = path.resolve(folder2watch, 'src', 'Home2.js')
63
+ let b = workspace.upsert(filePath2)
64
+ Promise.all([a, b])
65
+ .then(() => {
66
+ done()
67
+ })
68
+ .catch(done)
69
+ })
70
+
71
+ it('deve enviar de forma concorrente', async (done) => {
72
+ nock('https://dev.eitri.calindra.com.br')
73
+ .post('/workspace/fileupload')
74
+ .delayBody(1000)
75
+ .reply(200, { request: 1 })
76
+ nock('https://dev.eitri.calindra.com.br')
77
+ .post('/workspace/fileupload')
78
+ .delayBody(100)
79
+ .reply(200, { request: 2 })
80
+ let filePath = path.resolve(folder2watch, 'src', 'Home.js')
81
+ let filePath2 = path.resolve(folder2watch, 'src', 'Home2.js')
82
+ const data = await workspace.upsert([filePath, filePath2], {}, true)
83
+
84
+ data.forEach(result => {
85
+ expect(result.time).toBeTruthy()
86
+ expect(result.filePath).toBeTruthy()
87
+ expect(result.relativePath).toBeTruthy()
88
+ })
89
+ done()
90
+ })
91
+
92
+ it('deve retornar error se o fileName conter carácteres inválidos quando o arquivo for enviado sequencialmente', async () => {
93
+ let filePath = path.resolve(folder2watch, 'src', 'Homé.js')
94
+ const data = await workspace.upsert(filePath, {})
95
+ expect(data.message).toBe(' - No nome do arquivo possui um ou mais caracteres não permitidos: Homé.js')
96
+ })
97
+
98
+ it('deve retornar error se o fileName conter carácteres inválidos quando o arquivo for enviado concorrentemente', async () => {
99
+ let filePath = path.resolve(folder2watch, 'src', 'Homé.js')
100
+ const data = await workspace.upsert([filePath], {}, true)
101
+ expect(data.message).toBe(' - No nome do arquivo possui um ou mais caracteres não permitidos: Homé.js')
102
+ })
103
+ }, 10000)
104
+
105
+ describe('.delete(filePath)', () => {
106
+ it('pede para o servidor apagar o arquivo', async () => {
107
+ let scope = nock('https://dev.eitri.calindra.com.br')
108
+ .delete(/\/workspace\/fileupload.*/)
109
+ .reply(200, {})
110
+ let filePath = path.resolve(folder2watch, 'src', 'Home.js')
111
+ await workspace.delete(filePath)
112
+ expect(scope.isDone()).toBe(true)
113
+ })
114
+ })
115
+
116
+ describe('.listFilesInCorrectOrder()', () => {
117
+ it('concatena os componentes', async () => {
118
+ workspace.folder2watch = path.resolve(
119
+ __dirname,
120
+ '..',
121
+ '_fixtures',
122
+ 'src'
123
+ )
124
+ let files = await workspace.listFilesInCorrectOrder()
125
+ let names = files.map((fileName) => path.basename(fileName))
126
+ expect(names.slice(0, 4)).toEqual([
127
+ 'TagC.jsx',
128
+ 'TagB.jsx',
129
+ 'TagA.jsx',
130
+ 'TagD.jsx',
131
+ ])
132
+ })
133
+ })
134
+
135
+ describe('.getWorkspaceURL()', () => {
136
+ beforeEach(() => {
137
+ workspace.userEmail = 'dev@calindra.com.br'
138
+ workspace.target = {
139
+ bootstrapBaseUrl: 'http://minhaconta.base.url'
140
+ }
141
+ workspace.folder2watch = path.resolve(
142
+ __dirname,
143
+ '..',
144
+ '_fixtures',
145
+ 'src'
146
+ )
147
+ })
148
+
149
+ it('retorna a url do workspace do usuario apontando para index.html', async () => {
150
+ let url = await workspace.getWorkspaceURL('', {bootstrapBaseUrl: 'http://minhaconta.base.url'})
151
+ expect(url).toContain('/index.html?')
152
+ })
153
+
154
+ it('Deve retornar queries string ', async () => {
155
+ let args = {
156
+ initializationParams: {
157
+ foo: 'bar'
158
+ }
159
+ }
160
+ let urlValue = await workspace.getWorkspaceURL(args, {bootstrapBaseUrl: 'http://minhaconta.base.url'})
161
+ console.log(urlValue)
162
+ let query = url.parse(urlValue, true).query
163
+ let dataString = Buffer.from(query.data, 'base64').toString()
164
+ let data = JSON.parse(dataString)
165
+ expect(data.initializationParams).toMatchObject(args.initializationParams)
166
+ })
167
+
168
+ it('retorna a url do workspace do usuario apontando para OrderDetails.html', async () => {
169
+ let url = await workspace.getWorkspaceURL({ view: 'OrderDetails' }, {bootstrapBaseUrl: 'http://minhaconta.base.url'})
170
+ expect(url).toContain('/OrderDetails.html?')
171
+ })
172
+
173
+ it('retorna a url do workspace do usuario com o parametro order id', async () => {
174
+ let url = await workspace.getWorkspaceURL({
175
+ view: 'OrderDetails',
176
+ orderId: 'e08a2547-b8d6-4437-91a7-0bc67987689d',
177
+ }, {bootstrapBaseUrl: 'http://minhaconta.base.url'})
178
+ expect(url).toContain(
179
+ 'orderId=e08a2547-b8d6-4437-91a7-0bc67987689d'
180
+ )
181
+ })
182
+ })
183
+
184
+ describe('.postLambda()', () => {
185
+ const filePath = path.resolve(__dirname, '..', '_fixtures', 'src', 'server', 'foo.js')
186
+ const relativePath = '../_fixtures/src/server/foo.js'
187
+
188
+ beforeEach(() => {
189
+ nock.cleanAll()
190
+ workspace.setWebhooks([])
191
+ })
192
+ it('should on invoke postLambda set webhooks if return hookData', async () => {
193
+ const fakeHookData = {FunctionUrl: 'FakeUrl.com', fileName: 'fakeFileName'}
194
+ nock('https://dev.eitri.calindra.com.br', { allowUnmocked: true })
195
+ .post('/workspace/server', () => {
196
+ return true
197
+ })
198
+ .reply(200, { ok: true, hookData: fakeHookData })
199
+ await workspace.postLambda(filePath, relativePath)
200
+ const webhooks = workspace.getWebhooks()
201
+ expect(webhooks).toContainEqual(fakeHookData)
202
+ })
203
+
204
+ it('should on invoke postLambda ignore set webhooks if no return', async () => {
205
+ nock('https://dev.eitri.calindra.com.br', { allowUnmocked: true })
206
+ .post('/workspace/server', () => {
207
+ return true
208
+ })
209
+ .reply(200, { ok: true })
210
+ await workspace.postLambda(filePath, relativePath)
211
+ const webhooks = workspace.getWebhooks()
212
+ expect(webhooks).toEqual([])
213
+ })
214
+ })
215
+
216
+ describe('.getTargetConfig() & .getAllTargetConfigs()', () => {
217
+ const target = 'CALINDRA_MOBILE'
218
+ const res = [
219
+ {
220
+ id: 7,
221
+ name: 'CALINDRA_MOBILE',
222
+ minimumCliVersion: '1.16.5',
223
+ boilerplateUrl: 'https://github.com/Calindra/servless-backend-template.git',
224
+ superAppClientLibName: 'eitri-app-client',
225
+ componentsLibName: 'eitri-app-components',
226
+ description: 'CALINDRA_MOBILE',
227
+ status: 'ACTIVE',
228
+ platform: 'mobile',
229
+ targetConfig: [
230
+ {
231
+ id: 'default',
232
+ libUrl: 'https://www.npmjs.com/package/eitri-app-client',
233
+ runnerUrl: 'https://dev.eitri.calindra.com.br/app/',
234
+ bootstrapBaseUrl: 'https://dev.eitri.calindra.com.br',
235
+ askUserDataApiUrl: 'https://dev.eitri.calindra.com.br/miniapp-manager-api/o/mini-apps/:slug/token'
236
+ },
237
+ {
238
+ id: 'ws',
239
+ libUrl: 'https://www.npmjs.com/package/eitri-app-client',
240
+ runnerUrl: 'https://dev.eitri.calindra.com.br/app/',
241
+ bootstrapBaseUrl: 'http://localhost:3333',
242
+ askUserDataApiUrl: 'https://dev.eitri.calindra.com.br/miniapp-manager-api/p/mini-apps/:slug/token/workspace'
243
+ }
244
+ ],
245
+ default: true
246
+ }
247
+ ]
248
+
249
+ beforeEach(() => {
250
+ nock.cleanAll()
251
+ nock('https://dev.eitri.calindra.com.br')
252
+ .get(`/workspace/targets?name=${target}`).reply(200, res)
253
+ })
254
+
255
+ it('deve receber a configuração correta', async () => {
256
+ const config = await workspace.getTargetConfig('default', target)
257
+ expect(config[0]).toStrictEqual({
258
+ id: 'default',
259
+ libUrl: 'https://www.npmjs.com/package/eitri-app-client',
260
+ runnerUrl: 'https://dev.eitri.calindra.com.br/app/',
261
+ bootstrapBaseUrl: 'https://dev.eitri.calindra.com.br',
262
+ askUserDataApiUrl: 'https://dev.eitri.calindra.com.br/miniapp-manager-api/o/mini-apps/:slug/token'
263
+ })
264
+
265
+ }
266
+ )
267
+ it('deve retornar todos os configs', async () => {
268
+ const config = await workspace.getAllTargetConfigs(target)
269
+ expect(config).toMatchObject([
270
+ {
271
+ id: 'default',
272
+ libUrl: 'https://www.npmjs.com/package/eitri-app-client',
273
+ runnerUrl: 'https://dev.eitri.calindra.com.br/app/',
274
+ bootstrapBaseUrl: 'https://dev.eitri.calindra.com.br',
275
+ askUserDataApiUrl: 'https://dev.eitri.calindra.com.br/miniapp-manager-api/o/mini-apps/:slug/token'
276
+ },
277
+ {
278
+ id: 'ws',
279
+ libUrl: 'https://www.npmjs.com/package/eitri-app-client',
280
+ runnerUrl: 'https://dev.eitri.calindra.com.br/app/',
281
+ bootstrapBaseUrl: 'http://localhost:3333',
282
+ askUserDataApiUrl: 'https://dev.eitri.calindra.com.br/miniapp-manager-api/p/mini-apps/:slug/token/workspace'
283
+ }
284
+ ])
285
+ })
286
+ })
287
+
288
+ describe('.availableTargets()', () => {
289
+
290
+ const expectedTarget ={
291
+ 'id': 7,
292
+ 'name': 'CALINDRA_MOBILE',
293
+ 'minimumCliVersion': '1.16.5',
294
+ 'boilerplateUrl': 'https://github.com/Calindra/servless-backend-template',
295
+ 'superAppClientLibName': 'eitri-app-client',
296
+ 'componentsLibName': 'eitri-app-components',
297
+ 'description': 'CALINDRA_MOBILE',
298
+ 'status': 'ACTIVE',
299
+ 'platform': 'mobile',
300
+ 'targetConfig': [
301
+ {
302
+ 'id': 'default',
303
+ 'libUrl': 'https://www.npmjs.com/package/eitri-app-client',
304
+ 'runnerUrl': 'https://dev.eitri.calindra.com.br/app/',
305
+ 'bootstrapBaseUrl': 'http://localhost:3333',
306
+ 'askUserDataApiUrl': 'https://dev.eitri.calindra.com.br/miniapp-manager-api/o/mini-apps/:slug/token'
307
+ },
308
+ {
309
+ 'id': 'ws',
310
+ 'libUrl': 'https://www.npmjs.com/package/eitri-app-client',
311
+ 'runnerUrl': 'https://dev.eitri.calindra.com.br/app/',
312
+ 'bootstrapBaseUrl': 'http://localhost:3333',
313
+ 'askUserDataApiUrl': 'https://dev.eitri.calindra.com.br/miniapp-manager-api/p/mini-apps/:slug/token/workspace'
314
+ }
315
+ ],
316
+ 'default': false
317
+ }
318
+
319
+ it('should return targets', async () => {
320
+ nock('https://dev.eitri.calindra.com.br', { allowUnmocked: true })
321
+ .get('/workspace/targets')
322
+ .reply(200, [expectedTarget])
323
+ const result = await workspace.availableTargets()
324
+ expect(result).toBeDefined()
325
+ expect(result).toContainEqual(expectedTarget)
326
+ })
327
+ })
328
+
329
+ describe('.postFile()', () => {
330
+ afterEach(() => {
331
+ nock.cleanAll()
332
+ })
333
+ it('deve invocar o postLambda quando o relativePath incluir a pasta server', async () => {
334
+
335
+ nock('https://dev.eitri.calindra.com.br')
336
+ .post('/workspace/server')
337
+ .delayBody(1000)
338
+ .reply(200, { request: 1 })
339
+
340
+ const filePath = path.resolve(folder2watch, 'server', 'HelloWorldBackend.js')
341
+
342
+ const spiedPostLambda = jest.spyOn(workspace, 'postLambda')
343
+ await workspace.postFile(filePath, false, {})
344
+
345
+ expect(spiedPostLambda).toHaveBeenCalled()
346
+ expect(spiedPostLambda).toHaveBeenCalledTimes(1)
347
+ })
348
+
349
+ it('deve invocar o postFormData quando o relativePath incluir o watchDir do miniapp', async () => {
350
+ nock('https://dev.eitri.calindra.com.br')
351
+ .post('/workspace/fileupload')
352
+ .delayBody(1000)
353
+ .reply(200, { request: 1 })
354
+
355
+ const filePath = path.resolve(folder2watch, 'src', 'Home.js')
356
+
357
+ const spiedPostFormData = jest.spyOn(workspace, 'postFormData')
358
+ await workspace.postFile(filePath, false, {})
359
+
360
+ expect(spiedPostFormData).toHaveBeenCalled()
361
+ expect(spiedPostFormData).toHaveBeenCalledTimes(1)
362
+ })
363
+ })
364
+ })