Skip to content

Commit 73e244e

Browse files
afischerisaacwhite
andauthored
Resolve Circular Dependency (#360)
* Resolve utils --> list curcular dependency * Remove comment about circular dependency Co-authored-by: Isaac White <[email protected]> --------- Co-authored-by: Isaac White <[email protected]>
1 parent 17acfac commit 73e244e

File tree

8 files changed

+95
-87
lines changed

8 files changed

+95
-87
lines changed

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/docs.js

+1-18
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,20 @@
22

33
const {google} = require('googleapis')
44
const cheerio = require('cheerio')
5-
const slugify = require('slugify')
65
const xlsx = require('xlsx')
76

87
const cache = require('./cache')
98
const formatter = require('./formatter')
109
const log = require('./logger')
1110
const {getAuth} = require('./auth')
11+
const {slugify} = require('./utils')
1212

1313
const supportedTypes = new Set(['document', 'spreadsheet', 'text/html'])
1414

1515
const revisionSupportedArr = ['document', 'spreadsheet', 'presentation']
1616
const revisionSupported = new Set(revisionSupportedArr)
1717
const revisionMimeSupported = new Set(revisionSupportedArr.map((x) => `application/vnd.google-apps.${x}`))
1818

19-
exports.cleanName = (name = '') => {
20-
return name
21-
.trim()
22-
// eslint-disable-next-line no-useless-escape
23-
.replace(/^(\d+[-_\s]*)([^\d\/\-^\s]+)/, '$2') // remove leading numbers and delimiters
24-
.replace(/\s*\|\s*([^|]+)$/i, '') // remove trailing pipe and tags
25-
.replace(/\.[^.]+$/, '') // remove file extensions
26-
}
27-
28-
exports.slugify = (text = '') => {
29-
// convert non alpha numeric into whitespace, rather than removing
30-
const alphaNumeric = text.replace(/[^\p{L}\p{N}]+/ug, ' ')
31-
return slugify(alphaNumeric, {
32-
lower: true
33-
})
34-
}
35-
3619
exports.fetchDoc = async (id, resourceType, req) => {
3720
const data = await cache.get(id)
3821
if (data && data.content) {

server/list.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const cache = require('./cache')
88
const log = require('./logger')
99
const {getAuth} = require('./auth')
1010
const {isSupported} = require('./utils')
11-
const docs = require('./docs')
11+
const {slugify, cleanName} = require('./utils')
1212

1313
const driveType = process.env.DRIVE_TYPE
1414
const driveId = process.env.DRIVE_ID
@@ -170,9 +170,8 @@ function produceTree(files, firstParent) {
170170
const {parents, id, name, mimeType} = resource
171171

172172
// prepare data for the individual file and store later for reference
173-
// FIXME: consider how to remove circular dependency here.
174-
const prettyName = docs.cleanName(name)
175-
const slug = docs.slugify(prettyName)
173+
const prettyName = cleanName(name)
174+
const slug = slugify(prettyName)
176175
const tagString = (name.match(/\|\s*([^|]+)$/i) || [])[1] || ''
177176
const tags = tagString.split(',')
178177
.map((t) => t.trim().toLowerCase())

server/routes/categories.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ const router = require('express-promise-router')()
44

55
const log = require('../logger')
66
const {getMeta} = require('../list')
7-
const {fetchDoc, cleanName} = require('../docs')
7+
const {fetchDoc} = require('../docs')
8+
const {cleanName} = require('../utils')
89
const {getTemplates, sortDocs, stringTemplate, formatUrl, pathPrefix} = require('../utils')
910
const {parseUrl} = require('../urlParser')
1011

server/routes/playlists.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ const router = require('express-promise-router')()
44

55
const log = require('../logger')
66
const {getMeta, getPlaylist} = require('../list')
7-
const {fetchDoc, cleanName} = require('../docs')
8-
const {stringTemplate, formatUrl, pathPrefix} = require('../utils')
7+
const {fetchDoc} = require('../docs')
8+
const {stringTemplate, formatUrl, pathPrefix, cleanName} = require('../utils')
99
const {parseUrl} = require('../urlParser')
1010

1111
router.get('*', handlePlaylist)

server/utils.js

+18
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
const fs = require('fs')
33
const path = require('path')
44
const {promisify} = require('util')
5+
const slugify = require('slugify')
56
const yaml = require('js-yaml')
67
const {get: deepProp} = require('lodash')
78
const merge = require('deepmerge')
@@ -45,6 +46,23 @@ exports.sortDocs = (a, b) => {
4546
return b.resourceType === 'folder' ? 1 : -1
4647
}
4748

49+
exports.cleanName = (name = '') => {
50+
return name
51+
.trim()
52+
// eslint-disable-next-line no-useless-escape
53+
.replace(/^(\d+[-_\s]*)([^\d\/\-^\s]+)/, '$2') // remove leading numbers and delimiters
54+
.replace(/\s*\|\s*([^|]+)$/i, '') // remove trailing pipe and tags
55+
.replace(/\.[^.]+$/, '') // remove file extensions
56+
}
57+
58+
exports.slugify = (text = '') => {
59+
// convert non alpha numeric into whitespace, rather than removing
60+
const alphaNumeric = text.replace(/[^\p{L}\p{N}]+/ug, ' ')
61+
return slugify(alphaNumeric, {
62+
lower: true
63+
})
64+
}
65+
4866
// attempts to require from attemptPath. If file isn't present, looks for a
4967
// file of the same name in the server dir
5068
exports.requireWithFallback = (attemptPath) => {

test/unit/docs.test.js

+1-60
Original file line numberDiff line numberDiff line change
@@ -2,70 +2,11 @@
22

33
const {expect} = require('chai')
44

5-
const {cleanName, slugify, fetchDoc} = require('../../server/docs')
5+
const {fetchDoc} = require('../../server/docs')
66

77
const PAYLOAD_KEYS = ['html', 'byline', 'createdBy', 'sections']
88

99
describe('Docs', () => {
10-
describe('Name Cleaner', () => {
11-
it('should remove leading numbers and delimeters', () => {
12-
expect(cleanName('0000123abc12345')).equals('abc12345')
13-
expect(cleanName(' abc ')).equals('abc')
14-
expect(cleanName('123-abc')).equals('abc') // hyphen
15-
expect(cleanName('123–abc')).equals('abc') // en dash
16-
expect(cleanName('123—abc')).equals('abc') // em dash
17-
})
18-
19-
it('should remove trailing delimeters', () => {
20-
expect(cleanName('foo | thing')).equals('foo')
21-
expect(cleanName('one | two')).equals('one')
22-
expect(cleanName('one | two | three')).equals('one | two')
23-
})
24-
25-
it('should remove file extensions', () => {
26-
expect(cleanName('foo.html')).equals('foo')
27-
expect(cleanName('foo.txt')).equals('foo')
28-
expect(cleanName('nytimes.com.txt')).equals('nytimes.com')
29-
})
30-
31-
it('should not remove numbers when no text in the document name', () => {
32-
expect(cleanName('2018')).equals('2018')
33-
expect(cleanName('3/28')).equals('3/28')
34-
expect(cleanName('3-28-2018')).equals('3-28-2018')
35-
})
36-
37-
it('should only remove keywords preceded by a pipe', () => {
38-
expect(cleanName('Page foo | home')).equals('Page foo')
39-
expect(cleanName('Page foo home | home')).equals('Page foo home')
40-
expect(cleanName('Page foo hidden | home')).equals('Page foo hidden')
41-
expect(cleanName('Page foo home | home, hidden')).equals('Page foo home')
42-
expect(cleanName('Page foo home | hidden, home')).equals('Page foo home')
43-
})
44-
45-
it('should only remove words after the last pipe pipe', () => {
46-
expect(cleanName('I | love | pipes | home')).equals('I | love | pipes')
47-
expect(cleanName('I | love | pipes | foobar')).equals('I | love | pipes')
48-
})
49-
})
50-
51-
describe('Slugification', () => {
52-
it('should slugify simple phrases', () => {
53-
expect(slugify('this is a slug')).equals('this-is-a-slug')
54-
expect(slugify(' this is a slug ')).equals('this-is-a-slug')
55-
expect(slugify('this-is a slug')).equals('this-is-a-slug')
56-
expect(slugify('this... is a slug!')).equals('this-is-a-slug')
57-
expect(slugify('2018 this is a slug')).equals('2018-this-is-a-slug')
58-
})
59-
60-
it('should strip spacing', () => {
61-
expect(slugify(' slugify- me please ')).equals('slugify-me-please')
62-
})
63-
64-
it('should support diacritics', () => {
65-
expect(slugify('Öğretmenelere Öneriler')).equals('ogretmenelere-oneriler')
66-
})
67-
})
68-
6910
describe('Fetching Docs', () => {
7011
it('should fetch document data with expected structure', async () => {
7112
const doc = await fetchDoc('id-doc', 'document', {})

test/unit/utils.test.js

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
'use strict'
2+
3+
const {expect} = require('chai')
4+
5+
const {cleanName, slugify} = require('../../server/utils')
6+
7+
describe('Utils', () => {
8+
describe('Name Cleaner', () => {
9+
it('should remove leading numbers and delimeters', () => {
10+
expect(cleanName('0000123abc12345')).equals('abc12345')
11+
expect(cleanName(' abc ')).equals('abc')
12+
expect(cleanName('123-abc')).equals('abc') // hyphen
13+
expect(cleanName('123–abc')).equals('abc') // en dash
14+
expect(cleanName('123—abc')).equals('abc') // em dash
15+
})
16+
17+
it('should remove trailing delimeters', () => {
18+
expect(cleanName('foo | thing')).equals('foo')
19+
expect(cleanName('one | two')).equals('one')
20+
expect(cleanName('one | two | three')).equals('one | two')
21+
})
22+
23+
it('should remove file extensions', () => {
24+
expect(cleanName('foo.html')).equals('foo')
25+
expect(cleanName('foo.txt')).equals('foo')
26+
expect(cleanName('nytimes.com.txt')).equals('nytimes.com')
27+
})
28+
29+
it('should not remove numbers when no text in the document name', () => {
30+
expect(cleanName('2018')).equals('2018')
31+
expect(cleanName('3/28')).equals('3/28')
32+
expect(cleanName('3-28-2018')).equals('3-28-2018')
33+
})
34+
35+
it('should only remove keywords preceded by a pipe', () => {
36+
expect(cleanName('Page foo | home')).equals('Page foo')
37+
expect(cleanName('Page foo home | home')).equals('Page foo home')
38+
expect(cleanName('Page foo hidden | home')).equals('Page foo hidden')
39+
expect(cleanName('Page foo home | home, hidden')).equals('Page foo home')
40+
expect(cleanName('Page foo home | hidden, home')).equals('Page foo home')
41+
})
42+
43+
it('should only remove words after the last pipe pipe', () => {
44+
expect(cleanName('I | love | pipes | home')).equals('I | love | pipes')
45+
expect(cleanName('I | love | pipes | foobar')).equals('I | love | pipes')
46+
})
47+
})
48+
49+
describe('Slugification', () => {
50+
it('should slugify simple phrases', () => {
51+
expect(slugify('this is a slug')).equals('this-is-a-slug')
52+
expect(slugify(' this is a slug ')).equals('this-is-a-slug')
53+
expect(slugify('this-is a slug')).equals('this-is-a-slug')
54+
expect(slugify('this... is a slug!')).equals('this-is-a-slug')
55+
expect(slugify('2018 this is a slug')).equals('2018-this-is-a-slug')
56+
})
57+
58+
it('should strip spacing', () => {
59+
expect(slugify(' slugify- me please ')).equals('slugify-me-please')
60+
})
61+
62+
it('should support diacritics', () => {
63+
expect(slugify('Öğretmenelere Öneriler')).equals('ogretmenelere-oneriler')
64+
})
65+
})
66+
})

0 commit comments

Comments
 (0)