link_preview.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. process.env.NODE_ENV = 'test';
  2. let chai = require('chai');
  3. let server = require('../server');
  4. let should = chai.should();
  5. let expect = chai.expect;
  6. let getOGPreviewData = require('../lib/linkPreview/getOGPreviewData');
  7. let getPreviewHTML = require('../lib/linkPreview/getPreviewHTML');
  8. let linkPreview = require('../lib/linkPreview');
  9. let github = require('../lib/linkPreview/patterns/github');
  10. let wikipedia = require('../lib/linkPreview/patterns/wikipedia');
  11. let twitter = require('../lib/linkPreview/patterns/twitter');
  12. let amazon = require('../lib/linkPreview/patterns/amazon');
  13. const Errors = require('../lib/errors.js');
  14. chai.use(require('chai-http'));
  15. chai.use(require('chai-things'));
  16. describe('link_expansion', () => {
  17. //Wait for app to start before commencing
  18. before((done) => {
  19. if(server.locals.appStarted) done();
  20. server.on('appStarted', done);
  21. });
  22. describe('getOGPreviewData', () => {
  23. it('should return an object containing relevant OG data', async () => {
  24. let data = await getOGPreviewData('https://www.theguardian.com/news/2018/mar/17/cambridge-analytica-facebook-influence-us-election')
  25. data.should.have.property(
  26. 'title',
  27. 'Revealed: 50 million Facebook profiles harvested for Cambridge Analytica in major data breach'
  28. );
  29. data.should.have.property(
  30. 'description',
  31. 'Whistleblower describes how firm linked to former Trump adviser Steve Bannon compiled user data to target American voters• How Cambridge Analytica’s algorithms turned ‘likes’ into a political tool'
  32. );
  33. data.should.have.property(
  34. 'url',
  35. 'http://www.theguardian.com/news/2018/mar/17/cambridge-analytica-facebook-influence-us-election'
  36. );
  37. data.should.have.property(
  38. 'image',
  39. 'https://i.guim.co.uk/img/media/97532076a6935a1e79eba294437ed91f3eb4df6b/0_626_4480_2688/master/4480.jpg?w=1200&h=630&q=55&auto=format&usm=12&fit=crop&crop=faces%2Centropy&bm=normal&ba=bottom%2Cleft&blend64=aHR0cHM6Ly91cGxvYWRzLmd1aW0uY28udWsvMjAxOC8wMS8zMS9mYWNlYm9va19kZWZhdWx0LnBuZw&s=365825fe053733ae12f9b050f5374594'
  40. );
  41. });
  42. it('should use other meta or title tags if there is no OG tags availible', async () => {
  43. let data = await getOGPreviewData('http://ejs.co');
  44. data.should.have.property('title', 'EJS -- Embedded JavaScript templates');
  45. data.should.have.property(
  46. 'description',
  47. "'E' is for 'effective'. EJS is a simple templating language that lets you generate HTML markup with plain JavaScript. No religiousness about how to organize things. No reinvention of iteration and control-flow. It's just plain JavaScript."
  48. );
  49. });
  50. it('should return null if there is no OG tags availible', async () => {
  51. let data = await getOGPreviewData('http://blank.org');
  52. expect(data).to.be.null;
  53. });
  54. });
  55. describe('getPreviewHTML', () => {
  56. it('should return an HTML string for given object', () => {
  57. let HTML = getPreviewHTML({
  58. url: 'http://www.example.com',
  59. description: 'description',
  60. title: 'title',
  61. image: 'image'
  62. });
  63. (typeof HTML).should.equal('string');
  64. })
  65. it('should correctly deal with the conditional', () => {
  66. let HTML = getPreviewHTML({
  67. url: 'http://www.example.com',
  68. description: 'description',
  69. title: 'title'
  70. });
  71. (typeof HTML).should.equal('string');
  72. })
  73. });
  74. describe('linkPreview', () => {
  75. it('should get a HTML string from an OG link', async () => {
  76. let HTML = await linkPreview('https://www.theguardian.com/news/2018/mar/17/cambridge-analytica-facebook-influence-us-election');
  77. (typeof HTML).should.equal('string');
  78. HTML.length.should.be.above(0);
  79. });
  80. it('should get a HTML string from a custom pattern', async () => {
  81. let HTML = await linkPreview('https://en.wikipedia.org/wiki/google');
  82. (typeof HTML).should.equal('string');
  83. HTML.length.should.be.above(0);
  84. });
  85. it('should return an empty string from an invalid site', async () => {
  86. let HTML = await linkPreview('http://blank.org');
  87. (typeof HTML).should.equal('string');
  88. });
  89. });
  90. describe('GitHub', () => {
  91. it('should match a valid GitHub url', () => {
  92. github.matches('https://github.com/sbkwgh/forum').should.not.be.null;
  93. github.matches('http://github.com/sbkwgh/forum').should.not.be.null;
  94. expect(github.matches('http://notgithub.com/sbkwgh/forum')).to.be.null;
  95. });
  96. it('should return a data object', async () => {
  97. let data = await github.getPreviewData('https://github.com/sbkwgh/forum');
  98. data.should.have.property('title', 'sbkwgh/forum')
  99. data.should.have.property('url', 'https://github.com/sbkwgh/forum')
  100. data.should.have.property('description', 'Forum software created using Express, Vue, and Sequelize')
  101. });
  102. });
  103. describe('Wikipedia', () => {
  104. it('should match a valid Wikipedia url', () => {
  105. wikipedia.matches('https://en.wikipedia.org/wiki/google').should.not.be.null;
  106. wikipedia.matches('http://fr.wikipedia.org/wiki/google').should.not.be.null;
  107. expect(wikipedia.matches('http://en.wikipedia.org/notapage')).to.be.null;
  108. });
  109. it('should return a data object', async () => {
  110. let data = await wikipedia.getPreviewData('https://en.wikipedia.org/wiki/google');
  111. data.should.have.property('title', 'Google')
  112. data.should.have.property('url', 'https://en.wikipedia.org/wiki/Google')
  113. data.description.should.have.length(503)
  114. });
  115. });
  116. describe('Twitter', () => {
  117. it('should match a valid Wikipedia url', () => {
  118. twitter.matches('https://twitter.com/user/status/12345').should.not.be.null;
  119. expect(twitter.matches('http://twitter.com/notapage/123456')).to.be.null;
  120. expect(twitter.matches('http://twitter.com/notapage/status/qwertyu')).to.be.null;
  121. });
  122. it('should return a data object', async () => {
  123. let HTML = await twitter.getPreviewData('https://twitter.com/Interior/status/463440424141459456');
  124. (typeof HTML).should.equal('string');
  125. HTML.should.have.length.above(0);
  126. });
  127. });
  128. describe('Amazon', () => {
  129. it('should match a valid Amazon url', () => {
  130. amazon.matches('https://www.amazon.co.uk/gp/product/0199858616').should.not.be.null;
  131. amazon.matches('https://smile.amazon.co.uk/gp/product/0199858616').should.not.be.null;
  132. amazon.matches('https://www.amazon.co.uk/Betron-Isolating-Earphones-Headphones-Microphone-Black/dp/B01N1X4910').should.not.be.null;
  133. amazon.matches('http://amazon.co.uk/Sony-5-5-Inch-Android-SIM-Free-Smartphone-Gold/dp/B0792GT5T4/ref=dfg').should.not.be.null;
  134. expect(amazon.matches('https://www.amazon.co.uk/gp/dmusic/promotions/AmazonMusicUnlimited')).to.be.null;
  135. expect(amazon.matches('https://www.amazon.co.uk/')).to.be.null;
  136. });
  137. it('should return a correct data object', async () => {
  138. let data = await amazon.getPreviewData(
  139. `https://www.amazon.co.uk/gp/product/B005G39HUK/ref=s9u_ri_gw_i2?ie=UTF8&fpl=fresh&pd_rd_i=B005G39HUK&pd_rd_r=4edec2c7-2abc-11e8-9a21-019e4b2648c4&pd_rd_w=jtpWg&pd_rd_wg=lyBTu&pf_rd_m=A3P5ROKL5A1OLE&pf_rd_s=&pf_rd_r=8G2NPHM6AE411J2M0V6Z&pf_rd_t=36701&pf_rd_p=81d63d24-31ce-4958-9c19-bb66b139bc25&pf_rd_i=desktop`
  140. );
  141. data.should.have.property(
  142. 'description',
  143. "Fruit of the Loom Men's Super Premium Short Sleeve T-Shirt: Free UK Shipping on Orders Over £10 and Free 30-Day Returns on Selected Fashion Items sold or fulfilled by Amazon."
  144. );
  145. data.should.have.property(
  146. 'url',
  147. 'https://www.amazon.co.uk/gp/product/B005G39HUK'
  148. );
  149. data.should.have.property(
  150. 'title',
  151. "Fruit of the Loom Men's Super Premium Short Sleeve T-Shirt"
  152. );
  153. data.should.have.property(
  154. 'image',
  155. 'https://images-na.ssl-images-amazon.com/images/I/91q6n9sLPsL._UL1500_.jpg'
  156. );
  157. data.partial.includes('4.4 out of 5 stars').should.be.true;
  158. data.partial.includes('£1.20 - £19.99').should.be.true;
  159. });
  160. });
  161. })