plugins.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. /* tslint:disable:no-unused-expression */
  2. import 'mocha'
  3. import * as chai from 'chai'
  4. import {
  5. cleanupTests,
  6. closeAllSequelize,
  7. flushAndRunServer,
  8. getConfig, getMyUserInformation, getPluginPackageJSON,
  9. getPlugin,
  10. getPluginRegisteredSettings,
  11. getPluginsCSS,
  12. installPlugin, killallServers,
  13. listAvailablePlugins,
  14. listPlugins, reRunServer,
  15. ServerInfo,
  16. setAccessTokensToServers,
  17. setPluginVersion, uninstallPlugin,
  18. updateCustomSubConfig, updateMyUser, updatePluginPackageJSON, updatePlugin,
  19. updatePluginSettings,
  20. wait, getPublicSettings
  21. } from '../../../../shared/extra-utils'
  22. import { PluginType } from '../../../../shared/models/plugins/plugin.type'
  23. import { PeerTubePluginIndex } from '../../../../shared/models/plugins/peertube-plugin-index.model'
  24. import { ServerConfig } from '../../../../shared/models/server'
  25. import { PeerTubePlugin } from '../../../../shared/models/plugins/peertube-plugin.model'
  26. import { User } from '../../../../shared/models/users'
  27. import { PluginPackageJson } from '../../../../shared/models/plugins/plugin-package-json.model'
  28. import { RegisteredServerSettings } from '../../../../shared/models/plugins/register-server-setting.model'
  29. import { PublicServerSetting } from '../../../../shared/models/plugins/public-server.setting'
  30. const expect = chai.expect
  31. describe('Test plugins', function () {
  32. let server: ServerInfo = null
  33. before(async function () {
  34. this.timeout(30000)
  35. const configOverride = {
  36. plugins: {
  37. index: { check_latest_versions_interval: '5 seconds' }
  38. }
  39. }
  40. server = await flushAndRunServer(1, configOverride)
  41. await setAccessTokensToServers([ server ])
  42. })
  43. it('Should list and search available plugins and themes', async function () {
  44. this.timeout(30000)
  45. {
  46. const res = await listAvailablePlugins({
  47. url: server.url,
  48. accessToken: server.accessToken,
  49. count: 1,
  50. start: 0,
  51. pluginType: PluginType.THEME,
  52. search: 'background-red'
  53. })
  54. expect(res.body.total).to.be.at.least(1)
  55. expect(res.body.data).to.have.lengthOf(1)
  56. }
  57. {
  58. const res1 = await listAvailablePlugins({
  59. url: server.url,
  60. accessToken: server.accessToken,
  61. count: 2,
  62. start: 0,
  63. sort: 'npmName'
  64. })
  65. const data1: PeerTubePluginIndex[] = res1.body.data
  66. expect(res1.body.total).to.be.at.least(2)
  67. expect(data1).to.have.lengthOf(2)
  68. const res2 = await listAvailablePlugins({
  69. url: server.url,
  70. accessToken: server.accessToken,
  71. count: 2,
  72. start: 0,
  73. sort: '-npmName'
  74. })
  75. const data2: PeerTubePluginIndex[] = res2.body.data
  76. expect(res2.body.total).to.be.at.least(2)
  77. expect(data2).to.have.lengthOf(2)
  78. expect(data1[0].npmName).to.not.equal(data2[ 0 ].npmName)
  79. }
  80. {
  81. const res = await listAvailablePlugins({
  82. url: server.url,
  83. accessToken: server.accessToken,
  84. count: 10,
  85. start: 0,
  86. pluginType: PluginType.THEME,
  87. search: 'background-red',
  88. currentPeerTubeEngine: '1.0.0'
  89. })
  90. const data: PeerTubePluginIndex[] = res.body.data
  91. const p = data.find(p => p.npmName === 'peertube-theme-background-red')
  92. expect(p).to.be.undefined
  93. }
  94. })
  95. it('Should have an empty global css', async function () {
  96. const res = await getPluginsCSS(server.url)
  97. expect(res.text).to.be.empty
  98. })
  99. it('Should install a plugin and a theme', async function () {
  100. this.timeout(30000)
  101. await installPlugin({
  102. url: server.url,
  103. accessToken: server.accessToken,
  104. npmName: 'peertube-plugin-hello-world'
  105. })
  106. await installPlugin({
  107. url: server.url,
  108. accessToken: server.accessToken,
  109. npmName: 'peertube-theme-background-red'
  110. })
  111. })
  112. it('Should have the correct global css', async function () {
  113. const res = await getPluginsCSS(server.url)
  114. expect(res.text).to.contain('--mainBackgroundColor')
  115. })
  116. it('Should have the plugin loaded in the configuration', async function () {
  117. const res = await getConfig(server.url)
  118. const config: ServerConfig = res.body
  119. const theme = config.theme.registered.find(r => r.name === 'background-red')
  120. expect(theme).to.not.be.undefined
  121. const plugin = config.plugin.registered.find(r => r.name === 'hello-world')
  122. expect(plugin).to.not.be.undefined
  123. })
  124. it('Should update the default theme in the configuration', async function () {
  125. await updateCustomSubConfig(server.url, server.accessToken, { theme: { default: 'background-red' } })
  126. const res = await getConfig(server.url)
  127. const config: ServerConfig = res.body
  128. expect(config.theme.default).to.equal('background-red')
  129. })
  130. it('Should update my default theme', async function () {
  131. await updateMyUser({
  132. url: server.url,
  133. accessToken: server.accessToken,
  134. theme: 'background-red'
  135. })
  136. const res = await getMyUserInformation(server.url, server.accessToken)
  137. expect((res.body as User).theme).to.equal('background-red')
  138. })
  139. it('Should list plugins and themes', async function () {
  140. {
  141. const res = await listPlugins({
  142. url: server.url,
  143. accessToken: server.accessToken,
  144. count: 1,
  145. start: 0,
  146. pluginType: PluginType.THEME
  147. })
  148. const data: PeerTubePlugin[] = res.body.data
  149. expect(res.body.total).to.be.at.least(1)
  150. expect(data).to.have.lengthOf(1)
  151. expect(data[0].name).to.equal('background-red')
  152. }
  153. {
  154. const res = await listPlugins({
  155. url: server.url,
  156. accessToken: server.accessToken,
  157. count: 2,
  158. start: 0,
  159. sort: 'name'
  160. })
  161. const data: PeerTubePlugin[] = res.body.data
  162. expect(data[0].name).to.equal('background-red')
  163. expect(data[1].name).to.equal('hello-world')
  164. }
  165. {
  166. const res = await listPlugins({
  167. url: server.url,
  168. accessToken: server.accessToken,
  169. count: 2,
  170. start: 1,
  171. sort: 'name'
  172. })
  173. const data: PeerTubePlugin[] = res.body.data
  174. expect(data[0].name).to.equal('hello-world')
  175. }
  176. })
  177. it('Should get registered settings', async function () {
  178. const res = await getPluginRegisteredSettings({
  179. url: server.url,
  180. accessToken: server.accessToken,
  181. npmName: 'peertube-plugin-hello-world'
  182. })
  183. const registeredSettings = (res.body as RegisteredServerSettings).registeredSettings
  184. expect(registeredSettings).to.have.length.at.least(1)
  185. const adminNameSettings = registeredSettings.find(s => s.name === 'admin-name')
  186. expect(adminNameSettings).to.not.be.undefined
  187. })
  188. it('Should get public settings', async function () {
  189. const res = await getPublicSettings({ url: server.url, npmName: 'peertube-plugin-hello-world' })
  190. const publicSettings = (res.body as PublicServerSetting).publicSettings
  191. expect(Object.keys(publicSettings)).to.have.lengthOf(1)
  192. expect(Object.keys(publicSettings)).to.deep.equal([ 'user-name' ])
  193. expect(publicSettings['user-name']).to.be.null
  194. })
  195. it('Should update the settings', async function () {
  196. const settings = {
  197. 'admin-name': 'Cid'
  198. }
  199. await updatePluginSettings({
  200. url: server.url,
  201. accessToken: server.accessToken,
  202. npmName: 'peertube-plugin-hello-world',
  203. settings
  204. })
  205. })
  206. it('Should get a plugin and a theme', async function () {
  207. {
  208. const res = await getPlugin({
  209. url: server.url,
  210. accessToken: server.accessToken,
  211. npmName: 'peertube-plugin-hello-world'
  212. })
  213. const plugin: PeerTubePlugin = res.body
  214. expect(plugin.type).to.equal(PluginType.PLUGIN)
  215. expect(plugin.name).to.equal('hello-world')
  216. expect(plugin.description).to.exist
  217. expect(plugin.homepage).to.exist
  218. expect(plugin.uninstalled).to.be.false
  219. expect(plugin.enabled).to.be.true
  220. expect(plugin.description).to.exist
  221. expect(plugin.version).to.exist
  222. expect(plugin.peertubeEngine).to.exist
  223. expect(plugin.createdAt).to.exist
  224. expect(plugin.settings).to.not.be.undefined
  225. expect(plugin.settings['admin-name']).to.equal('Cid')
  226. }
  227. {
  228. const res = await getPlugin({
  229. url: server.url,
  230. accessToken: server.accessToken,
  231. npmName: 'peertube-theme-background-red'
  232. })
  233. const plugin: PeerTubePlugin = res.body
  234. expect(plugin.type).to.equal(PluginType.THEME)
  235. expect(plugin.name).to.equal('background-red')
  236. expect(plugin.description).to.exist
  237. expect(plugin.homepage).to.exist
  238. expect(plugin.uninstalled).to.be.false
  239. expect(plugin.enabled).to.be.true
  240. expect(plugin.description).to.exist
  241. expect(plugin.version).to.exist
  242. expect(plugin.peertubeEngine).to.exist
  243. expect(plugin.createdAt).to.exist
  244. expect(plugin.settings).to.be.null
  245. }
  246. })
  247. it('Should update the plugin and the theme', async function () {
  248. this.timeout(30000)
  249. // Wait the scheduler that get the latest plugins versions
  250. await wait(6000)
  251. // Fake update our plugin version
  252. await setPluginVersion(server.internalServerNumber, 'hello-world', '0.0.1')
  253. // Fake update package.json
  254. const packageJSON: PluginPackageJson = await getPluginPackageJSON(server, 'peertube-plugin-hello-world')
  255. const oldVersion = packageJSON.version
  256. packageJSON.version = '0.0.1'
  257. await updatePluginPackageJSON(server, 'peertube-plugin-hello-world', packageJSON)
  258. // Restart the server to take into account this change
  259. killallServers([ server ])
  260. await reRunServer(server)
  261. {
  262. const res = await listPlugins({
  263. url: server.url,
  264. accessToken: server.accessToken,
  265. pluginType: PluginType.PLUGIN
  266. })
  267. const plugin: PeerTubePlugin = res.body.data[0]
  268. expect(plugin.version).to.equal('0.0.1')
  269. expect(plugin.latestVersion).to.exist
  270. expect(plugin.latestVersion).to.not.equal('0.0.1')
  271. }
  272. {
  273. await updatePlugin({
  274. url: server.url,
  275. accessToken: server.accessToken,
  276. npmName: 'peertube-plugin-hello-world'
  277. })
  278. const res = await listPlugins({
  279. url: server.url,
  280. accessToken: server.accessToken,
  281. pluginType: PluginType.PLUGIN
  282. })
  283. const plugin: PeerTubePlugin = res.body.data[0]
  284. expect(plugin.version).to.equal(oldVersion)
  285. const updatedPackageJSON: PluginPackageJson = await getPluginPackageJSON(server, 'peertube-plugin-hello-world')
  286. expect(updatedPackageJSON.version).to.equal(oldVersion)
  287. }
  288. })
  289. it('Should uninstall the plugin', async function () {
  290. await uninstallPlugin({
  291. url: server.url,
  292. accessToken: server.accessToken,
  293. npmName: 'peertube-plugin-hello-world'
  294. })
  295. const res = await listPlugins({
  296. url: server.url,
  297. accessToken: server.accessToken,
  298. pluginType: PluginType.PLUGIN
  299. })
  300. expect(res.body.total).to.equal(0)
  301. expect(res.body.data).to.have.lengthOf(0)
  302. })
  303. it('Should have an empty global css', async function () {
  304. const res = await getPluginsCSS(server.url)
  305. expect(res.text).to.be.empty
  306. })
  307. it('Should list uninstalled plugins', async function () {
  308. const res = await listPlugins({
  309. url: server.url,
  310. accessToken: server.accessToken,
  311. pluginType: PluginType.PLUGIN,
  312. uninstalled: true
  313. })
  314. expect(res.body.total).to.equal(1)
  315. expect(res.body.data).to.have.lengthOf(1)
  316. const plugin: PeerTubePlugin = res.body.data[0]
  317. expect(plugin.name).to.equal('hello-world')
  318. expect(plugin.enabled).to.be.false
  319. expect(plugin.uninstalled).to.be.true
  320. })
  321. it('Should uninstall the theme', async function () {
  322. await uninstallPlugin({
  323. url: server.url,
  324. accessToken: server.accessToken,
  325. npmName: 'peertube-theme-background-red'
  326. })
  327. })
  328. it('Should have updated the configuration', async function () {
  329. // get /config (default theme + registered themes + registered plugins)
  330. const res = await getConfig(server.url)
  331. const config: ServerConfig = res.body
  332. expect(config.theme.default).to.equal('default')
  333. const theme = config.theme.registered.find(r => r.name === 'background-red')
  334. expect(theme).to.be.undefined
  335. const plugin = config.plugin.registered.find(r => r.name === 'hello-world')
  336. expect(plugin).to.be.undefined
  337. })
  338. it('Should have updated the user theme', async function () {
  339. const res = await getMyUserInformation(server.url, server.accessToken)
  340. expect((res.body as User).theme).to.equal('instance-default')
  341. })
  342. after(async function () {
  343. await closeAllSequelize([ server ])
  344. await cleanupTests([ server ])
  345. })
  346. })