You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

305 lines
8.2 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. 'use strict'
  2. const test = require('tape')
  3. const request = require('req-then')
  4. const localWebServer = require('../')
  5. const http = require('http')
  6. const PassThrough = require('stream').PassThrough
  7. function launchServer (app, options) {
  8. options = options || {}
  9. const path = `http://localhost:8100${options.path || '/'}`
  10. const server = http.createServer(app.callback())
  11. return server.listen(options.port || 8100, () => {
  12. const req = request(path, options.reqOptions)
  13. if (options.onSuccess) req.then(options.onSuccess)
  14. if (!options.leaveOpen) req.then(() => server.close())
  15. req.catch(err => console.error('LAUNCH ERROR', err.stack))
  16. })
  17. }
  18. function checkResponse (t, status, body) {
  19. return function (response) {
  20. if (status) t.strictEqual(response.res.statusCode, status)
  21. if (body) t.ok(body.test(response.data))
  22. }
  23. }
  24. test('serve-index', function (t) {
  25. t.plan(2)
  26. const app = localWebServer({
  27. log: { format: 'none' },
  28. serveIndex: {
  29. path: __dirname + '/fixture',
  30. options: {
  31. icons: true
  32. }
  33. }
  34. })
  35. launchServer(app, { onSuccess: response => {
  36. t.ok(/listing directory/.test(response.data))
  37. t.ok(/class="icon/.test(response.data))
  38. }})
  39. })
  40. test('single page app', function (t) {
  41. t.plan(6)
  42. const app = localWebServer({
  43. log: { format: 'none' },
  44. static: { root: __dirname + '/fixture/spa' },
  45. spa: 'one.txt'
  46. })
  47. const server = http.createServer(app.callback())
  48. server.listen(8100, () => {
  49. /* text/html requests for missing files redirect to spa */
  50. request('http://localhost:8100/asdf', { headers: { accept: 'text/html' } })
  51. .then(checkResponse(t, 200, /one/))
  52. /* html requests for missing files with extensions do not redirect to spa */
  53. .then(() => request('http://localhost:8100/asdf.txt', { headers: { accept: 'text/html' } }))
  54. .then(checkResponse(t, 404))
  55. /* existing static file */
  56. .then(() => request('http://localhost:8100/two.txt'))
  57. .then(checkResponse(t, 200, /two/))
  58. /* not a text/html request - does not redirect to spa */
  59. .then(() => request('http://localhost:8100/asdf'))
  60. .then(checkResponse(t, 404))
  61. .then(server.close.bind(server))
  62. })
  63. })
  64. test('log: common', function (t) {
  65. t.plan(1)
  66. const stream = PassThrough()
  67. stream.on('readable', () => {
  68. let chunk = stream.read()
  69. if (chunk) t.ok(/GET/.test(chunk.toString()))
  70. })
  71. const app = localWebServer({
  72. log: {
  73. format: 'common',
  74. options: {
  75. stream: stream
  76. }
  77. }
  78. })
  79. launchServer(app)
  80. })
  81. test('compress', function (t) {
  82. t.plan(1)
  83. const app = localWebServer({
  84. compress: true,
  85. log: { format: 'none' },
  86. static: { root: __dirname + '/fixture' }
  87. })
  88. launchServer(
  89. app,
  90. {
  91. reqOptions: { headers: { 'Accept-Encoding': 'gzip' } },
  92. path: '/big-file.txt',
  93. onSuccess: response => {
  94. t.strictEqual(response.res.headers['content-encoding'], 'gzip')
  95. }
  96. }
  97. )
  98. })
  99. test('mime', function (t) {
  100. t.plan(2)
  101. const app = localWebServer({
  102. log: { format: 'none' },
  103. static: { root: __dirname + '/fixture' },
  104. mime: { 'text/plain': [ 'php' ] }
  105. })
  106. launchServer(app, { path: '/something.php', onSuccess: response => {
  107. t.strictEqual(response.res.statusCode, 200)
  108. t.ok(/text\/plain/.test(response.res.headers['content-type']))
  109. }})
  110. })
  111. test('forbid', function (t) {
  112. t.plan(2)
  113. const app = localWebServer({
  114. log: { format: 'none' },
  115. static: { root: __dirname + '/fixture/forbid' },
  116. forbid: [ '*.php', '*.html' ]
  117. })
  118. const server = launchServer(app, { leaveOpen: true })
  119. request('http://localhost:8100/two.php')
  120. .then(response => {
  121. t.strictEqual(response.res.statusCode, 403)
  122. request('http://localhost:8100/one.html')
  123. .then(response => {
  124. t.strictEqual(response.res.statusCode, 403)
  125. server.close()
  126. })
  127. })
  128. })
  129. test('rewrite: local', function (t) {
  130. t.plan(1)
  131. const app = localWebServer({
  132. log: { format: 'none' },
  133. static: { root: __dirname + '/fixture/rewrite' },
  134. rewrite: [ { from: '/two.html', to: '/one.html' } ]
  135. })
  136. launchServer(app, { path: '/two.html', onSuccess: response => {
  137. t.ok(/one/.test(response.data))
  138. }})
  139. })
  140. test('mock: simple response', function (t) {
  141. t.plan(2)
  142. const app = localWebServer({
  143. log: { format: 'none' },
  144. mocks: [
  145. { route: '/test', response: { body: 'test' } }
  146. ]
  147. })
  148. launchServer(app, { path: '/test', onSuccess: response => {
  149. t.strictEqual(response.res.statusCode, 200)
  150. t.ok(/test/.test(response.data))
  151. }})
  152. })
  153. test('mock: method request filter', function (t) {
  154. t.plan(3)
  155. const app = localWebServer({
  156. log: { format: 'none' },
  157. mocks: [
  158. {
  159. route: '/test',
  160. request: { method: 'POST' },
  161. response: { body: 'test' }
  162. }
  163. ]
  164. })
  165. const server = http.createServer(app.callback())
  166. server.listen(8100, () => {
  167. request('http://localhost:8100/test')
  168. .then(checkResponse(t, 404))
  169. .then(() => request('http://localhost:8100/test', { data: 'something' }))
  170. .then(checkResponse(t, 200, /test/))
  171. .then(server.close.bind(server))
  172. })
  173. })
  174. test('mock: accepts request filter', function (t) {
  175. t.plan(3)
  176. const app = localWebServer({
  177. log: { format: 'none' },
  178. mocks: [
  179. {
  180. route: '/test',
  181. request: { accepts: 'text' },
  182. response: { body: 'test' }
  183. }
  184. ]
  185. })
  186. const server = http.createServer(app.callback())
  187. server.listen(8100, () => {
  188. request('http://localhost:8100/test', { headers: { Accept: '*/json' } })
  189. .then(checkResponse(t, 404))
  190. .then(() => request('http://localhost:8100/test', { headers: { Accept: 'text/plain' } }))
  191. .then(checkResponse(t, 200, /test/))
  192. .then(server.close.bind(server))
  193. })
  194. })
  195. test('mock: responses array', function (t) {
  196. t.plan(4)
  197. const app = localWebServer({
  198. log: { format: 'none' },
  199. mocks: [
  200. {
  201. route: '/test',
  202. responses: [
  203. { request: { method: 'GET' }, response: { body: 'get' } },
  204. { request: { method: 'POST' }, response: { body: 'post' } }
  205. ]
  206. }
  207. ]
  208. })
  209. const server = http.createServer(app.callback())
  210. server.listen(8100, () => {
  211. request('http://localhost:8100/test')
  212. .then(checkResponse(t, 200, /get/))
  213. .then(() => request('http://localhost:8100/test', { method: 'POST' }))
  214. .then(checkResponse(t, 200, /post/))
  215. .then(server.close.bind(server))
  216. })
  217. })
  218. test('mock: response function', function (t) {
  219. t.plan(4)
  220. const app = localWebServer({
  221. log: { format: 'none' },
  222. mocks: [
  223. {
  224. route: '/test',
  225. responses: [
  226. { request: { method: 'GET' }, response: ctx => ctx.body = 'get' },
  227. { request: { method: 'POST' }, response: ctx => ctx.body = 'post' }
  228. ]
  229. }
  230. ]
  231. })
  232. const server = http.createServer(app.callback())
  233. server.listen(8100, () => {
  234. request('http://localhost:8100/test')
  235. .then(checkResponse(t, 200, /get/))
  236. .then(() => request('http://localhost:8100/test', { method: 'POST' }))
  237. .then(checkResponse(t, 200, /post/))
  238. .then(server.close.bind(server))
  239. })
  240. })
  241. test('mock: response function args', function (t) {
  242. t.plan(2)
  243. const app = localWebServer({
  244. log: { format: 'none' },
  245. mocks: [
  246. {
  247. route: '/test/:one',
  248. responses: [
  249. { request: { method: 'GET' }, response: (ctx, one) => ctx.body = one }
  250. ]
  251. }
  252. ]
  253. })
  254. const server = http.createServer(app.callback())
  255. server.listen(8100, () => {
  256. request('http://localhost:8100/test/yeah')
  257. .then(checkResponse(t, 200, /yeah/))
  258. .then(server.close.bind(server))
  259. })
  260. })
  261. test('mock: async response function', function (t) {
  262. t.plan(2)
  263. const app = localWebServer({
  264. log: { format: 'none' },
  265. mocks: [
  266. {
  267. route: '/test',
  268. responses: {
  269. response: function (ctx) {
  270. return new Promise((resolve, reject) => {
  271. setTimeout(() => {
  272. ctx.body = 'test'
  273. resolve()
  274. }, 10)
  275. })
  276. }
  277. }
  278. }
  279. ]
  280. })
  281. const server = http.createServer(app.callback())
  282. server.listen(8100, () => {
  283. request('http://localhost:8100/test')
  284. .then(checkResponse(t, 200, /test/))
  285. .then(server.close.bind(server))
  286. })
  287. })