bv-ui-core 0.1.1

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/.eslintrc +40 -0
  2. package/.travis.yml +5 -0
  3. package/CONTRIBUTING.md +98 -0
  4. package/LICENSE.md +13 -0
  5. package/OWNERS +2 -0
  6. package/README.md +63 -0
  7. package/catalog-info.yaml +30 -0
  8. package/karma.conf.js +130 -0
  9. package/lib/README.md +61 -0
  10. package/lib/api/.babelrc +3 -0
  11. package/lib/api/.eslintrc +9 -0
  12. package/lib/api/README.md +134 -0
  13. package/lib/api/index.js +15 -0
  14. package/lib/api/statistics.js +148 -0
  15. package/lib/application/README.md +96 -0
  16. package/lib/application/index.js +171 -0
  17. package/lib/body/README.md +13 -0
  18. package/lib/body/index.js +19 -0
  19. package/lib/bvFetch/README.md +101 -0
  20. package/lib/bvFetch/index.js +383 -0
  21. package/lib/checkHighContrast/README.md +26 -0
  22. package/lib/checkHighContrast/index.js +36 -0
  23. package/lib/cookie/README.md +29 -0
  24. package/lib/cookie/index.js +111 -0
  25. package/lib/cookieConsent/README.md +41 -0
  26. package/lib/cookieConsent/index.js +227 -0
  27. package/lib/cssLoadChecker/README.md +19 -0
  28. package/lib/cssLoadChecker/index.js +72 -0
  29. package/lib/date.now/README.md +11 -0
  30. package/lib/date.now/index.js +40 -0
  31. package/lib/domainPolice/README.md +66 -0
  32. package/lib/domainPolice/index.js +95 -0
  33. package/lib/evented/README.md +42 -0
  34. package/lib/evented/index.js +135 -0
  35. package/lib/getOriginalConstructor/README.md +16 -0
  36. package/lib/getOriginalConstructor/index.js +52 -0
  37. package/lib/global/README.md +10 -0
  38. package/lib/global/index.js +48 -0
  39. package/lib/ie/README.md +13 -0
  40. package/lib/ie/index.js +25 -0
  41. package/lib/loader/README.md +73 -0
  42. package/lib/loader/index.js +358 -0
  43. package/lib/logger/README.md +82 -0
  44. package/lib/logger/index.js +180 -0
  45. package/lib/messageFormat/README.md +10 -0
  46. package/lib/messageFormat/index.js +42 -0
  47. package/lib/namespacer/README.md +57 -0
  48. package/lib/namespacer/index.js +98 -0
  49. package/lib/performance/README.md +35 -0
  50. package/lib/performance/entries.js +5 -0
  51. package/lib/performance/getEntries.js +42 -0
  52. package/lib/performance/getEntriesByName.js +61 -0
  53. package/lib/performance/getEntriesByType.js +55 -0
  54. package/lib/performance/index.js +11 -0
  55. package/lib/performance/mark.js +97 -0
  56. package/lib/performance/measure.js +106 -0
  57. package/lib/performance/now.js +63 -0
  58. package/lib/pixelsDisplayed/README.md +19 -0
  59. package/lib/pixelsDisplayed/index.js +113 -0
  60. package/lib/polyfills/README.md +39 -0
  61. package/lib/polyfills/fetch/Headers.js +3 -0
  62. package/lib/polyfills/fetch/Request.js +3 -0
  63. package/lib/polyfills/fetch/Response.js +3 -0
  64. package/lib/polyfills/fetch/fetch.js +3 -0
  65. package/lib/polyfills/fetch/index.js +57 -0
  66. package/lib/polyfills/promise.js +265 -0
  67. package/lib/queryShadowDom/README.md +50 -0
  68. package/lib/queryShadowDom/index.js +93 -0
  69. package/lib/region/README.md +64 -0
  70. package/lib/region/europe/index.js +94 -0
  71. package/lib/region/europe/territories.js +40 -0
  72. package/lib/region/index.js +123 -0
  73. package/lib/staticAssetLoader/README.md +116 -0
  74. package/lib/staticAssetLoader/index.js +248 -0
  75. package/lib/waitForBody/README.md +21 -0
  76. package/lib/waitForBody/index.js +36 -0
  77. package/mkdocs.yaml +5 -0
  78. package/package.json +55 -0
  79. package/test/.eslintrc +5 -0
  80. package/test/fixtures/lib.loader.document-is-wrong-in-ie8.js +5 -0
  81. package/test/fixtures/lib.loader.loadscript-attribute.js +3 -0
  82. package/test/fixtures/lib.loader.loadscript.js +3 -0
  83. package/test/fixtures/lib.loader.loadstylesheet.css +3 -0
  84. package/test/unit/api/.eslintrc +6 -0
  85. package/test/unit/api/index.spec.js +37 -0
  86. package/test/unit/api/response.json +67 -0
  87. package/test/unit/api/statistics.spec.js +218 -0
  88. package/test/unit/application/index.spec.js +313 -0
  89. package/test/unit/body/index.spec.js +15 -0
  90. package/test/unit/bvFetch/index.spec.js +246 -0
  91. package/test/unit/checkHighContrast/index.spec.js +16 -0
  92. package/test/unit/cookie/index.spec.js +191 -0
  93. package/test/unit/cookieConsent/index.spec.js +119 -0
  94. package/test/unit/cssLoadChecker/index.spec.js +75 -0
  95. package/test/unit/date.now/index.spec.js +21 -0
  96. package/test/unit/domainPolice/index.spec.js +141 -0
  97. package/test/unit/evented/index.spec.js +59 -0
  98. package/test/unit/getOriginalConstructor/index.spec.js +60 -0
  99. package/test/unit/global/index.spec.js +84 -0
  100. package/test/unit/ie/index.spec.js +14 -0
  101. package/test/unit/loader/index.spec.js +644 -0
  102. package/test/unit/logger/index.spec.js +141 -0
  103. package/test/unit/messageFormat/index.spec.js +31 -0
  104. package/test/unit/mochaInit.js +8 -0
  105. package/test/unit/namespacer/index.spec.js +100 -0
  106. package/test/unit/performance/getEntries.spec.js +30 -0
  107. package/test/unit/performance/getEntriesByName.spec.js +88 -0
  108. package/test/unit/performance/getEntriesByType.spec.js +48 -0
  109. package/test/unit/performance/index.spec.js +35 -0
  110. package/test/unit/performance/mark.spec.js +40 -0
  111. package/test/unit/performance/measure.spec.js +50 -0
  112. package/test/unit/performance/now.spec.js +21 -0
  113. package/test/unit/pixelsDisplayed/index.spec.js +271 -0
  114. package/test/unit/polyfills/fetch/Headers.js +12 -0
  115. package/test/unit/polyfills/fetch/Request.js +12 -0
  116. package/test/unit/polyfills/fetch/Response.js +12 -0
  117. package/test/unit/polyfills/fetch/fetch.js +12 -0
  118. package/test/unit/polyfills/fetch/index.js +61 -0
  119. package/test/unit/polyfills/promise.spec.js +48 -0
  120. package/test/unit/region/europe/index.spec.js +70 -0
  121. package/test/unit/region/index.spec.js +113 -0
  122. package/test/unit/staticAssetLoader/index.spec.js +215 -0
@@ -0,0 +1,21 @@
1
+ # waitForBody
2
+
3
+ This file exposes a utility function that will invoke its callback once the
4
+ `document.body` tag has been created by the runtime environment. It is
5
+ intended to be used in the case of scripts that execute synchronously in the
6
+ head of a document, prior to document.body being available, yet having a
7
+ dependency on document.body for some reason (e.g. appending DOM nodes). This
8
+ function uses a MutationObserver in order to function, so requires that level
9
+ of support in order to function.
10
+
11
+ ## Usage
12
+ ```javascript
13
+ var waitForBody = require('bv-ui-core/lib/waitForBody');
14
+
15
+ var div = document.createElement('div');
16
+ div.id = 'modalContainer';
17
+
18
+ waitForBody(function () {
19
+ document.body.appendChild(div);
20
+ });
21
+ ```
@@ -0,0 +1,36 @@
1
+ /**
2
+ * This file exposes a single function that can be used to monitor for
3
+ * document.body to come into existence. It does not mean that its DOM
4
+ * is loaded, it only means that the document.body node has been created.
5
+ */
6
+
7
+ function checkForBody (callback, documentMutationObserver) {
8
+ if (document.body) {
9
+ // Stop observing the root documentElement
10
+ documentMutationObserver.disconnect()
11
+
12
+ // Invoke the callback
13
+ callback()
14
+ }
15
+ }
16
+
17
+ module.exports = function waitForBody (callback) {
18
+ // If document.body is ready, bail early
19
+ if (document.body) {
20
+ callback()
21
+ return
22
+ }
23
+
24
+ // In case the document.body element doesn't exist yet, set up a mutation
25
+ // observer on document.documentElement, and each time it's triggered,
26
+ // check for document.body... When it exists, stop observing this.
27
+ var documentMutationObserver = new MutationObserver(function () {
28
+ checkForBody(callback, documentMutationObserver)
29
+ })
30
+
31
+ // Attach to document.documentElement for monitoring
32
+ documentMutationObserver.observe(document.documentElement, { childList: true, subtree: true })
33
+
34
+ // Invoke once, in case document.body already exists
35
+ checkForBody(callback, documentMutationObserver)
36
+ }
package/mkdocs.yaml ADDED
@@ -0,0 +1,5 @@
1
+ site_name: bv-ui-core
2
+ docs_dir: lib
3
+ plugins:
4
+ - techdocs-core
5
+ repo_url: https://github.com/bazaarvoice/bv-ui-core/
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "bv-ui-core",
3
+ "version": "0.1.1",
4
+ "license": "Apache 2.0",
5
+ "description": "Bazaarvoice UI-related JavaScript",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git://github.com/bazaarvoice/bv-ui-core"
9
+ },
10
+ "engines": {
11
+ "node": ">=10.*"
12
+ },
13
+ "scripts": {
14
+ "lint": "eslint karma.conf.js lib test",
15
+ "test": "./node_modules/karma/bin/karma start --single-run --browsers ChromeHeadless",
16
+ "dev": "./node_modules/karma/bin/karma start --browsers Chrome"
17
+ },
18
+ "devDependencies": {
19
+ "babel-core": "^6.26.3",
20
+ "babel-loader": "^6.4.1",
21
+ "babel-plugin-lodash": "^3.3.4",
22
+ "babel-polyfill": "^6.26.0",
23
+ "babel-preset-es2015": "^6.24.1",
24
+ "chai": "^3.5.0",
25
+ "eslint": "2.2.0",
26
+ "ghooks": "1.0.3",
27
+ "istanbul-instrumenter-loader": "0.2.0",
28
+ "json-loader": "^0.5.7",
29
+ "karma": "^3.0.0",
30
+ "karma-chai": "^0.1.0",
31
+ "karma-chrome-launcher": "^2.0.0",
32
+ "karma-coverage": "^1.1.2",
33
+ "karma-firefox-launcher": "^1.1.0",
34
+ "karma-htmlfile-reporter": "^0.3.6",
35
+ "karma-mocha": "^1.3.0",
36
+ "karma-sinon": "^1.0.5",
37
+ "karma-sinon-chai": "^1.3.4",
38
+ "karma-webpack": "^1.7.0",
39
+ "lodash": "^4.17.10",
40
+ "mocha": "^5.2.0",
41
+ "node-libs-browser": "1.0.0",
42
+ "sinon": "^4.5.0",
43
+ "sinon-chai": "^2.14.0",
44
+ "webpack": "^1.15.0"
45
+ },
46
+ "config": {
47
+ "ghooks": {
48
+ "pre-commit": "npm run lint",
49
+ "pre-push": "npm run lint && npm test"
50
+ }
51
+ },
52
+ "dependencies": {
53
+ "whatwg-fetch": "^2.0.3"
54
+ }
55
+ }
package/test/.eslintrc ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "env": {
3
+ "mocha": true
4
+ }
5
+ }
@@ -0,0 +1,5 @@
1
+ /* global libLoaderTestCallback: false, document: false */
2
+
3
+ setTimeout(function () {
4
+ libLoaderTestCallback(document);
5
+ }, 10);
@@ -0,0 +1,3 @@
1
+ /* global libLoaderAttributeTestCallback: false */
2
+
3
+ libLoaderAttributeTestCallback();
@@ -0,0 +1,3 @@
1
+ /* global libLoaderTestCallback: false */
2
+
3
+ libLoaderTestCallback();
@@ -0,0 +1,3 @@
1
+ #canary {
2
+ width: 100px;
3
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "env": {
3
+ "es6": true,
4
+ "browser": true
5
+ }
6
+ }
@@ -0,0 +1,37 @@
1
+ var api = require('../../../lib/api')
2
+
3
+ describe('api', function () {
4
+ let oldFetch
5
+
6
+ before(() => {
7
+ oldFetch = window.fetch
8
+ window.fetch = () => Promise.resolve({
9
+ json: () => ({
10
+ Results: [],
11
+ }),
12
+ })
13
+ })
14
+
15
+ after(() => {
16
+ window.fetch = oldFetch
17
+ })
18
+
19
+ describe('get', () => {
20
+ it('should throw if unsupported type', () => {
21
+ expect(function () {
22
+ api.get('foo')
23
+ }).to.throw('Unsupported method: foo')
24
+ })
25
+ it('should works for statistics', () => {
26
+ api.get('statistics', {
27
+ productIds: ['product1', 'product2', 'product3'],
28
+ environment: 'qa',
29
+ key: 'clients_api_key',
30
+ type: 'Reviews',
31
+ filters: {
32
+ ContentLocale: 'en_US'
33
+ }
34
+ })
35
+ })
36
+ })
37
+ })
@@ -0,0 +1,67 @@
1
+ {
2
+ "Includes":{
3
+
4
+ },
5
+ "HasErrors":false,
6
+ "Offset":0,
7
+ "TotalResults":4,
8
+ "Locale":"en_US",
9
+ "Errors":[
10
+
11
+ ],
12
+ "Results":[
13
+ {
14
+ "ProductStatistics":{
15
+ "NativeReviewStatistics":{
16
+
17
+ },
18
+ "ReviewStatistics":{
19
+ "TotalReviewCount":0,
20
+ "AverageOverallRating":null,
21
+ "OverallRatingRange":5
22
+ },
23
+ "ProductId":"Product4"
24
+ }
25
+ },
26
+ {
27
+ "ProductStatistics":{
28
+ "NativeReviewStatistics":{
29
+
30
+ },
31
+ "ReviewStatistics":{
32
+ "TotalReviewCount":2,
33
+ "AverageOverallRating":2.0,
34
+ "OverallRatingRange":5
35
+ },
36
+ "ProductId":"Product3"
37
+ }
38
+ },
39
+ {
40
+ "ProductStatistics":{
41
+ "NativeReviewStatistics":{
42
+
43
+ },
44
+ "ReviewStatistics":{
45
+ "TotalReviewCount":1,
46
+ "AverageOverallRating":5.0,
47
+ "OverallRatingRange":5
48
+ },
49
+ "ProductId":"Product2"
50
+ }
51
+ },
52
+ {
53
+ "ProductStatistics":{
54
+ "NativeReviewStatistics":{
55
+
56
+ },
57
+ "ReviewStatistics":{
58
+ "TotalReviewCount":48,
59
+ "AverageOverallRating":4.0208,
60
+ "OverallRatingRange":5
61
+ },
62
+ "ProductId":"Product1"
63
+ }
64
+ }
65
+ ],
66
+ "Limit":4
67
+ }
@@ -0,0 +1,218 @@
1
+ /**
2
+ * @fileOverview Tests for API.
3
+ *
4
+ * These tests will fail unless run in a browser due to whatwg-fetch polyfill.
5
+ *
6
+ * @module test/apicacherequest
7
+ */
8
+ let _ = require('lodash')
9
+
10
+ const API_RESULT_SUCCESS = require('json!./response.json')
11
+
12
+ const mockFetchSuccess = () => {
13
+ return {
14
+ then: () => {
15
+ return {
16
+ then: (callback) => {
17
+ let apiResult = API_RESULT_SUCCESS
18
+ callback(apiResult)
19
+ }
20
+ }
21
+ }
22
+ }
23
+ }
24
+
25
+ const mockFetchFail = () => {
26
+ return {
27
+ then: () => {
28
+ return {
29
+ then: (callback) => {
30
+ let apiResult = {
31
+ HasErrors: true,
32
+ Errors: [{
33
+ Message: 'An error occurred.'
34
+ }]
35
+ }
36
+ callback(apiResult)
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+ const mockFetchFailMissingError = () => {
44
+ return {
45
+ then: () => {
46
+ return {
47
+ then: (callback) => {
48
+ let apiResult = {
49
+ HasErrors: true
50
+ }
51
+ callback(apiResult)
52
+ }
53
+ }
54
+ }
55
+ }
56
+ }
57
+
58
+ let getStatistics = require('../../../lib/api/statistics')
59
+
60
+ describe('getStatistics', () => {
61
+ const oldFetch = window.fetch
62
+
63
+ after(() => {
64
+ window.fetch = oldFetch
65
+ })
66
+
67
+ beforeEach(() => {
68
+ window.fetch = mockFetchSuccess
69
+ })
70
+
71
+ describe('parameter validation', () => {
72
+ it('should throw if not provided productIds', () => {
73
+ expect(() => getStatistics({
74
+ environment: 'qa',
75
+ key: 'clients_api_key',
76
+ type: 'Reviews',
77
+ filters: {
78
+ ContentLocale: 'en_US'
79
+ }
80
+ })).to.throw('productIds must be an array')
81
+ })
82
+
83
+ it('should throw if provided non-array productIds', () => {
84
+ let invalids = ['product1', { id: 'product1' }]
85
+ for (let productId in invalids) {
86
+ expect(() => getStatistics({
87
+ productIds: productId,
88
+ environment: 'qa',
89
+ key: 'clients_api_key',
90
+ type: 'Reviews',
91
+ filters: {
92
+ ContentLocale: 'en_US'
93
+ }
94
+ })).to.throw('productIds must be an array')
95
+ }
96
+ })
97
+
98
+ it('should throw if not provided environment', () => {
99
+ expect(() => getStatistics({
100
+ productIds: ['product1', 'product2', 'product3'],
101
+ key: 'clients_api_key',
102
+ type: 'Reviews',
103
+ filters: {
104
+ ContentLocale: 'en_US'
105
+ }
106
+ })).to.throw('environment must be "qa", "staging", or "production"')
107
+ })
108
+
109
+ it('should throw if provided invalid environment', () => {
110
+ let invalids = ['dev', 'stg', 'prod']
111
+
112
+ for (let environment in invalids) {
113
+ expect(() => getStatistics({
114
+ productIds: ['product1', 'product2', 'product3'],
115
+ environment: environment,
116
+ key: 'clients_api_key',
117
+ type: 'Reviews',
118
+ filters: {
119
+ ContentLocale: 'en_US'
120
+ }
121
+ })).to.throw('environment must be "qa", "staging", or "production"')
122
+ }
123
+ })
124
+
125
+ it('should throw if not provided key', () => {
126
+ expect(() => getStatistics({
127
+ productIds: ['product1', 'product2', 'product3'],
128
+ environment: 'qa',
129
+ type: 'Reviews',
130
+ filters: {
131
+ ContentLocale: 'en_US'
132
+ }
133
+ })).to.throw('key must be provided')
134
+ })
135
+
136
+ it('should throw if not provided type', () => {
137
+ expect(() => getStatistics({
138
+ productIds: ['product1', 'product2', 'product3'],
139
+ environment: 'qa',
140
+ key: 'clients_api_key',
141
+ filters: {
142
+ ContentLocale: 'en_US'
143
+ }
144
+ })).to.throw('type must be "Reviews" or "NativeReviews"')
145
+ })
146
+
147
+ it('should throw if provided invalid type', () => {
148
+ expect(() => getStatistics({
149
+ productIds: ['product1', 'product2', 'product3'],
150
+ environment: 'qa',
151
+ key: 'clients_api_key',
152
+ filters: {
153
+ ContentLocale: 'en_US'
154
+ },
155
+ type: 'reviews'
156
+ })).to.throw('type must be "Reviews" or "NativeReviews"')
157
+ })
158
+ })
159
+
160
+ it('should work in general', () => {
161
+ return getStatistics({
162
+ productIds: ['product1', 'product2', 'product3'],
163
+ environment: 'qa',
164
+ key: 'clients_api_key',
165
+ type: 'Reviews',
166
+ filters: {
167
+ ContentLocale: 'en_US'
168
+ }
169
+ })
170
+ })
171
+
172
+ it('should work for requests over 100', () => {
173
+ const products = _.range(1, 300).map(id => `product${id}`)
174
+
175
+ return getStatistics({
176
+ productIds: products,
177
+ environment: 'qa',
178
+ key: 'clients_api_key',
179
+ type: 'Reviews',
180
+ filters: {
181
+ ContentLocale: 'en_US'
182
+ }
183
+ })
184
+ })
185
+
186
+ it('should return an error', (done) => {
187
+ window.fetch = mockFetchFail
188
+ getStatistics({
189
+ productIds: ['product1', 'product2', 'product3'],
190
+ environment: 'qa',
191
+ key: 'clients_api_key',
192
+ type: 'Reviews',
193
+ filters: {
194
+ ContentLocale: 'en_US'
195
+ }
196
+ }).then(() => {}, error => {
197
+ expect(error.Message).to.equal('An error occurred.')
198
+ done()
199
+ })
200
+ })
201
+
202
+ it('should return ERROR_UNKNOWN error if error is missing from response', (done) => {
203
+ window.fetch = mockFetchFailMissingError
204
+ getStatistics({
205
+ productIds: ['product1', 'product2', 'product3'],
206
+ environment: 'qa',
207
+ key: 'clients_api_key',
208
+ type: 'Reviews',
209
+ filters: {
210
+ ContentLocale: 'en_US'
211
+ }
212
+ }).then(() => {}, error => {
213
+ expect(error.Message).to.equal('An unknown error occurred.')
214
+ expect(error.Code).to.equal('ERROR_UNKNOWN')
215
+ done()
216
+ })
217
+ })
218
+ })