├── .env-sample
├── .github
└── workflows
│ └── test-logic-and-interface.yml
├── .gitignore
├── Dockerfile
├── LICENSE.md
├── README.md
├── captain-definition
├── os-app
├── _shared
│ ├── ZDABank
│ │ ├── main-tests.js
│ │ └── main.js
│ └── common
│ │ ├── controller.js
│ │ └── ui-style.css
├── api-projects
│ ├── controller-tests.js
│ └── controller.js
├── open-glance
│ ├── controller.js
│ ├── i18n-en.yml
│ ├── ui-behaviour.js
│ ├── ui-style.css
│ ├── ui-test-_access.js
│ ├── ui-test-_localize.js
│ ├── ui-test-_misc.js
│ └── ui-view.ejs
├── open-vitrine
│ ├── controller.js
│ ├── i18n-en.yml
│ ├── i18n-es.yml
│ ├── i18n-fr.yml
│ ├── i18n-pt.yml
│ ├── ui-style.css
│ ├── ui-test-_access.js
│ ├── ui-test-_localize.js
│ ├── ui-test-_misc.js
│ └── ui-view.ejs
├── sub-events
│ ├── controller.js
│ ├── i18n-en.yml
│ ├── i18n-es.yml
│ ├── i18n-fr.yml
│ ├── i18n-pt.yml
│ ├── ui-test-_access.js
│ ├── ui-test-_localize.js
│ ├── ui-test-_misc.js
│ └── ui-view.ejs
├── sub-list
│ ├── controller.js
│ ├── i18n-en.yml
│ ├── i18n-es.yml
│ ├── i18n-fr.yml
│ ├── i18n-pt.yml
│ ├── ui-test-_access.js
│ ├── ui-test-_localize.js
│ ├── ui-test-_misc.js
│ └── ui-view.ejs
├── task-a-banks
│ ├── controller-tests.js
│ └── controller.js
├── task-b-details
│ ├── controller-tests.js
│ └── controller.js
├── task-c-images
│ ├── controller-tests.js
│ └── controller.js
├── task-d-events
│ ├── controller-tests.js
│ └── controller.js
└── tech-robots
│ ├── controller.js
│ └── ui-test-_misc.js
├── package-postinstall.js
└── package.json
/.env-sample:
--------------------------------------------------------------------------------
1 | # Copy this file to '.env' if not created by `npm run setup`
2 |
3 | ZDA_VITRINE_FLOWS_TRADITIONAL_URL=https://static.rosano.ca/0data/flowtraditional.svg
4 | ZDA_VITRINE_FLOWS_MODERN_URL=https://static.rosano.ca/0data/flowmodern.svg
5 | ZDA_TASK_BANKS_URLS="https://remotestorage.io/apps,https://github.com/0dataapp/unofficial-fission-apps-list,https://github.com/0dataapp/awesome-0data/raw/master/README.md,https://unhosted.org/apps,https://solidproject.org/apps"
6 | ZDA_TASK_EVENTS_URLS="https://community.remotestorage.io/c/events/12.rss,https://lu.ma/embed-events/usr-q0wId4DZFlx7LCP,https://www.eventbrite.co.uk/o/solid-project-30026804546"
7 | ZDA_VITRINE_GROUP_DISCUSSION_VIDEO_URL="https://www.youtube-nocookie.com/embed/UNKgD8OzjCk"
8 | ZDA_VITRINE_IDENTITY_URL=https://static.rosano.ca/0data/identity.svg
9 | ZDA_VITRINE_EASY_INDIE_URL=https://easyIndie.app
10 | ZDA_VITRINE_EASY_INDIE_IDENTITY_URL=https://static.rosano.ca/easyindieapp/identity.svg
11 |
12 | SWAR_LINK_URL=https://ring.0data.app
13 |
14 | OLSK_REPO_URL=https://github.com/0dataapp/0data
15 |
16 | ROCO_SHARED_PROJECT_ID=RP_005
17 |
--------------------------------------------------------------------------------
/.github/workflows/test-logic-and-interface.yml:
--------------------------------------------------------------------------------
1 | name: Test logic and interface
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | test-logic-and-interface:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@v2
10 | - name: Configure Node.js
11 | uses: actions/setup-node@v1
12 | with:
13 | node-version: '14.x'
14 | - name: Install dependencies
15 | run: npm run setup
16 | - name: Test logic
17 | run: npm run test -- --ci
18 | - name: Test interface
19 | run: OLSK_FLAG_CI=true OLSK_SPEC_PLAYWRIGHT=true npx start-server-and-test start 3000 'olsk-spec-ui --ci'
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # NODE
2 | node_modules
3 | package-lock.json
4 |
5 | # BUILD
6 | **/__*/*
7 | .static
8 |
9 | # LOCAL
10 | .env*
11 | !.env-sample
12 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:16
2 | RUN mkdir -p /usr/src/app
3 | WORKDIR /usr/src/app
4 | COPY ./package.json /usr/src/app/
5 | COPY ./package-postinstall.js /usr/src/app/
6 | ARG CACHE_BUST=11
7 | RUN npm install
8 | COPY ./ /usr/src/app
9 | ENV NODE_ENV production
10 | ENV PORT 80
11 | EXPOSE 80
12 | CMD [ "npm", "start" ]
13 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (2020) (Rosano Coutinho)
2 |
3 | Hippocratic License Version Number: 2.1.
4 |
5 | * Purpose. The purpose of this License is for the Licensor named above to permit the Licensee (as defined below) broad permission, if consistent with Human Rights Laws and Human Rights Principles (as each is defined below), to use and work with the Software (as defined below) within the full scope of Licensor's copyright and patent rights, if any, in the Software, while ensuring attribution and protecting the Licensor from liability.
6 |
7 | * Permission and Conditions. The Licensor grants permission by this license ("License"), free of charge, to the extent of Licensor's rights under applicable copyright and patent law, to any person or entity (the "Licensee") obtaining a copy of this software and associated documentation files (the "Software"), to do everything with the Software that would otherwise infringe (i) the Licensor's copyright in the Software or (ii) any patent claims to the Software that the Licensor can license or becomes able to license, subject to all of the following terms and conditions:
8 |
9 | * Acceptance. This License is automatically offered to every person and entity subject to its terms and conditions. Licensee accepts this License and agrees to its terms and conditions by taking any action with the Software that, absent this License, would infringe any intellectual property right held by Licensor.
10 |
11 | * Notice. Licensee must ensure that everyone who gets a copy of any part of this Software from Licensee, with or without changes, also receives the License and the above copyright notice (and if included by the Licensor, patent, trademark and attribution notice). Licensee must cause any modified versions of the Software to carry prominent notices stating that Licensee changed the Software. For clarity, although Licensee is free to create modifications of the Software and distribute only the modified portion created by Licensee with additional or different terms, the portion of the Software not modified must be distributed pursuant to this License. If anyone notifies Licensee in writing that Licensee has not complied with this Notice section, Licensee can keep this License by taking all practical steps to comply within 30 days after the notice. If Licensee does not do so, Licensee's License (and all rights licensed hereunder) shall end immediately.
12 |
13 | * Compliance.
14 |
15 | 1. Human Rights Principles.
16 |
17 | (a) Licensee is advised to consult the articles of the United Nations Universal Declaration of Human Rights and the United Nations Global Compact that define recognized principles of international human rights (the "Human Rights Principles"). Licensee shall use the Software in a manner consistent with Human Rights Principles.
18 |
19 | (b) Unless the Licensor and Licensee agree otherwise, any dispute, controversy, or claim arising out of or relating to (i) Section 1(a) regarding Human Rights Principles, including the breach of Section 1(a), termination of this License for breach of the Human Rights Principles, or invalidity of Section 1(a) or (ii) a determination of whether any Law is consistent or in conflict with Human Rights Principles pursuant to Section 2, below, shall be settled by arbitration in accordance with the Hague Rules on Business and Human Rights Arbitration (the "Rules"); provided, however, that Licensee may elect not to participate in such arbitration, in which event this License (and all rights licensed hereunder) shall end immediately. The number of arbitrators shall be one unless the Rules require otherwise.
20 |
21 | Unless both the Licensor and Licensee agree to the contrary: (1) All documents and information concerning the arbitration shall be public and may be disclosed by any party; (2) The repository referred to under Article 43 of the Rules shall make available to the public in a timely manner all documents concerning the arbitration which are communicated to it, including all submissions of the parties, all evidence admitted into the record of the proceedings, all transcripts or other recordings of hearings and all orders, decisions and awards of the arbitral tribunal, subject only to the arbitral tribunal's powers to take such measures as may be necessary to safeguard the integrity of the arbitral process pursuant to Articles 18, 33, 41 and 42 of the Rules; and (3) Article 26(6) of the Rules shall not apply.
22 |
23 | 2. Human Rights Laws. The Software shall not be used by any person or entity for any systems, activities, or other uses that violate any Human Rights Laws. "Human Rights Laws" means any applicable laws, regulations, or rules (collectively, "Laws") that protect human, civil, labor, privacy, political, environmental, security, economic, due process, or similar rights; provided, however, that such Laws are consistent and not in conflict with Human Rights Principles (a dispute over the consistency or a conflict between Laws and Human Rights Principles shall be determined by arbitration as stated above). Where the Human Rights Laws of more than one jurisdiction are applicable or in conflict with respect to the use of the Software, the Human Rights Laws that are most protective of the individuals or groups harmed shall apply.
24 |
25 | 3. [Surveillance Capitalism](https://en.wikipedia.org/wiki/Surveillance_capitalism). The Software shall not be used by any person or entity for any systems, activities, or other uses that actively and knowingly participate in data gathering for the purpose of advertising or surveillance capitalism.
26 |
27 | 4. Large commercial actors. For-profit entities earning revenues in excess of $1,000,000 USD per year must obtain approval from the copyright holder and purchase a paid licence in order to use the Software in commercial projects.
28 |
29 | 5. Indemnity. Licensee shall hold harmless and indemnify Licensor (and any other contributor) against all losses, damages, liabilities, deficiencies, claims, actions, judgments, settlements, interest, awards, penalties, fines, costs, or expenses of whatever kind, including Licensor's reasonable attorneys' fees, arising out of or relating to Licensee's use of the Software in violation of Human Rights Laws or Human Rights Principles.
30 |
31 | * Failure to Comply. Any failure of Licensee to act according to the terms and conditions of this License is both a breach of the License and an infringement of the intellectual property rights of the Licensor (subject to exceptions under Laws, e.g., fair use). In the event of a breach or infringement, the terms and conditions of this License may be enforced by Licensor under the Laws of any jurisdiction to which Licensee is subject. Licensee also agrees that the Licensor may enforce the terms and conditions of this License against Licensee through specific performance (or similar remedy under Laws) to the extent permitted by Laws. For clarity, except in the event of a breach of this License, infringement, or as otherwise stated in this License, Licensor may not terminate this License with Licensee.
32 |
33 | * Enforceability and Interpretation. If any term or provision of this License is determined to be invalid, illegal, or unenforceable by a court of competent jurisdiction, then such invalidity, illegality, or unenforceability shall not affect any other term or provision of this License or invalidate or render unenforceable such term or provision in any other jurisdiction; provided, however, subject to a court modification pursuant to the immediately following sentence, if any term or provision of this License pertaining to Human Rights Laws or Human Rights Principles is deemed invalid, illegal, or unenforceable against Licensee by a court of competent jurisdiction, all rights in the Software granted to Licensee shall be deemed null and void as between Licensor and Licensee. Upon a determination that any term or provision is invalid, illegal, or unenforceable, to the extent permitted by Laws, the court may modify this License to affect the original purpose that the Software be used in compliance with Human Rights Principles and Human Rights Laws as closely as possible. The language in this License shall be interpreted as to its fair meaning and not strictly for or against any party.
34 |
35 | * Disclaimer. TO THE FULL EXTENT ALLOWED BY LAW, THIS SOFTWARE COMES "AS IS," WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED, AND LICENSOR AND ANY OTHER CONTRIBUTOR SHALL NOT BE LIABLE TO ANYONE FOR ANY DAMAGES OR OTHER LIABILITY ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THIS LICENSE, UNDER ANY KIND OF LEGAL CLAIM.
36 |
37 | This Hippocratic License is an Ethical Source license (https://ethicalsource.dev) and is offered for use by licensors and licensees at their own risk, on an "AS IS" basis, and with no warranties express or implied, to the maximum extent permitted by Laws.
38 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # [Zero Data App](https://0data.app)
4 |
5 | _Own your data, all of it._
6 |
7 | ## Data compiled automatically from the following locations:
8 |
9 | ### Apps
10 | - https://remotestorage.io/apps
11 | - https://github.com/0dataapp/unofficial-fission-apps-list
12 | - https://github.com/0dataapp/awesome-0data
13 | - https://unhosted.org/apps
14 | - https://solidproject.org/apps
15 |
16 | | Metadata | Source |
17 | | - | - |
18 | | Icon | `` on the app website or [`icons`](https://developer.mozilla.org/en-US/docs/Web/Manifest/icons) from the manifest |
19 |
20 | ### Protocols
21 | - https://github.com/0dataapp/awesome-0data
22 |
23 | ### Tools
24 | - https://github.com/0dataapp/awesome-0data
25 |
26 | ### Events
27 | - https://community.remotestorage.io/c/events/12.rss
28 | - https://lu.ma/embed-events/usr-q0wId4DZFlx7LCP
29 | - https://www.eventbrite.co.uk/o/solid-project-30026804546
30 | - https://chat.0data.app/c/events/5.rss
31 |
32 | ## Architecture
33 |
34 | The project follows a [Universal folder structure](https://rosano.hmm.garden/01f71kp52knc5nnv08qr9kzj3m) and is a large collection of mostly small modules or functions. With the exception of a few 'global' or 'magic' things such as the localization function `OLSKLocalized`, most resources used by a module should be in the same folder or referenced by path name.
35 |
36 | Routing, rendering markdown content, and serving pages is done via a Node.js server (usually configured in the *controller.js* files).
37 |
38 | ## Development Setup
39 |
40 | (For a deeper dive, watch [the tutorial](https://rosano.hmm.garden/01f62t5yseb053m024v1mczbzy)).
41 |
42 | Install [Node.js and npm](https://nodejs.org/en/download/), then:
43 |
44 | ```
45 | npm run setup
46 | ```
47 |
48 | This should create an `.env` file if there is none. If you encounter errors referring to this file, you can find missing variables in `.env-sample`.
49 |
50 | ## Running
51 |
52 | ```
53 | npm start
54 | ```
55 |
56 | It should be accessible at http://localhost:3000.
57 |
58 | ## Testing
59 |
60 | See [Testing logic and interfaces](https://rosano.hmm.garden/01f7v3hk3txz5d0v9ms467x8bz) for a tutorial.
61 |
62 | ### Run logic tests
63 |
64 | ```
65 | npm test
66 | ```
67 |
68 | ### Run interface tests
69 |
70 | ```
71 | npm test ui
72 | ```
73 |
74 | To filter interface test paths by string:
75 |
76 | ```
77 | npm test ui match=vitrine
78 | ```
79 |
80 | To filter interface test paths by JavaScript regular expressions:
81 |
82 | ```
83 | npm test ui match='/(list|robots)/'
84 | ```
85 |
86 | ## ❤️
87 |
88 | Help me keep creating projects that are public, accessible for free, and open-source.
89 |
90 |
91 |
92 | ## License
93 |
94 | The code is released under a [Hippocratic License](https://firstdonoharm.dev), modified to exclude its use for surveillance capitalism and also to require large for-profit entities to purchase a paid license.
95 |
96 | ## Questions
97 |
98 | Feel free to reach out on [Mastodon](https://rosano.ca/mastodon) or [Twitter](https://rosano.ca/twitter).
99 |
--------------------------------------------------------------------------------
/captain-definition:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": 2,
3 | "dockerfilePath" : "./Dockerfile"
4 | }
5 |
--------------------------------------------------------------------------------
/os-app/_shared/ZDABank/main-tests.js:
--------------------------------------------------------------------------------
1 | const { throws, rejects, deepEqual } = require('assert');
2 |
3 | const mod = require('./main.js');
4 |
5 | describe('ZDABankURLs', function test_ZDABankURLs() {
6 |
7 | it('returns array', function () {
8 | deepEqual(mod.ZDABankURLs(), process.env.ZDA_TASK_BANKS_URLS.split(','));
9 | });
10 |
11 | });
12 |
13 | describe('ZDABankURLRemoteStorage', function test_ZDABankURLRemoteStorage() {
14 |
15 | it('returns string', function () {
16 | deepEqual(mod.ZDABankURLRemoteStorage(), mod.ZDABankURLs().filter(function (e) {
17 | return e.match(/RemoteStorage/i);
18 | }).shift());
19 | });
20 |
21 | });
22 |
23 | describe('ZDABankURLFission', function test_ZDABankURLFission() {
24 |
25 | it('returns string', function () {
26 | deepEqual(mod.ZDABankURLFission(), mod.ZDABankURLs().filter(function (e) {
27 | return e.match(/Fission/i);
28 | }).shift());
29 | });
30 |
31 | });
32 |
33 | describe('ZDABankURLAwesome', function test_ZDABankURLAwesome() {
34 |
35 | it('returns string', function () {
36 | deepEqual(mod.ZDABankURLAwesome(), mod.ZDABankURLs().filter(function (e) {
37 | return e.match(/Awesome/i);
38 | }).shift());
39 | });
40 |
41 | });
42 |
43 | describe('ZDABankURLUnhosted', function test_ZDABankURLUnhosted() {
44 |
45 | it('returns string', function () {
46 | deepEqual(mod.ZDABankURLUnhosted(), mod.ZDABankURLs().filter(function (e) {
47 | return e.match(/Unhosted/i);
48 | }).shift());
49 | });
50 |
51 | });
52 |
53 | describe('ZDABankURLSolidProject', function test_ZDABankURLSolidProject() {
54 |
55 | it('returns string', function () {
56 | deepEqual(mod.ZDABankURLSolidProject(), mod.ZDABankURLs().filter(function (e) {
57 | return e.match(/Solid/i);
58 | }).shift());
59 | });
60 |
61 | });
62 |
63 | describe('ZDABankProtocolProperties', function test_ZDABankProtocolProperties() {
64 |
65 | it('returns object', function () {
66 | deepEqual(mod.ZDABankProtocolProperties(), {
67 | ZDABankRemoteStorage: {
68 | ZDAProtocolName: 'remoteStorage',
69 | },
70 | ZDABankFission: {
71 | ZDAProtocolName: 'Fission',
72 | },
73 | ZDABankAwesome: {},
74 | ZDABankUnhosted: {},
75 | ZDABankSolidProject: {
76 | ZDAProtocolName: 'Solid',
77 | },
78 | });
79 | });
80 |
81 | });
82 |
--------------------------------------------------------------------------------
/os-app/_shared/ZDABank/main.js:
--------------------------------------------------------------------------------
1 | const mod = {
2 |
3 | ZDABankURLs() {
4 | return process.env.ZDA_TASK_BANKS_URLS.split(',');
5 | },
6 |
7 | ZDABankURLRemoteStorage () {
8 | return mod.ZDABankURLs().filter(function (e) {
9 | return e.match(/RemoteStorage/i);
10 | }).shift();
11 | },
12 |
13 | ZDABankURLFission () {
14 | return mod.ZDABankURLs().filter(function (e) {
15 | return e.match(/Fission/i);
16 | }).shift();
17 | },
18 |
19 | ZDABankURLAwesome () {
20 | return mod.ZDABankURLs().filter(function (e) {
21 | return e.match(/Awesome/i);
22 | }).shift();
23 | },
24 |
25 | ZDABankURLUnhosted () {
26 | return mod.ZDABankURLs().filter(function (e) {
27 | return e.match(/Unhosted/i);
28 | }).shift();
29 | },
30 |
31 | ZDABankURLSolidProject () {
32 | return mod.ZDABankURLs().filter(function (e) {
33 | return e.match(/Solid/i);
34 | }).shift();
35 | },
36 |
37 | ZDABankProtocolProperties () {
38 | return mod.ZDABankURLs().reduce(function (coll, item) {
39 | return Object.assign(coll, {
40 | [{
41 | [mod.ZDABankURLRemoteStorage()]: 'ZDABankRemoteStorage',
42 | [mod.ZDABankURLFission()]: 'ZDABankFission',
43 | [mod.ZDABankURLAwesome()]: 'ZDABankAwesome',
44 | [mod.ZDABankURLUnhosted()]: 'ZDABankUnhosted',
45 | [mod.ZDABankURLSolidProject()]: 'ZDABankSolidProject',
46 | }[item]]: {
47 | [mod.ZDABankURLRemoteStorage()]: {
48 | ZDAProtocolName: 'remoteStorage',
49 | },
50 | [mod.ZDABankURLFission()]: {
51 | ZDAProtocolName: 'Fission',
52 | },
53 | [mod.ZDABankURLAwesome()]: {},
54 | [mod.ZDABankURLUnhosted()]: {},
55 | [mod.ZDABankURLSolidProject()]: {
56 | ZDAProtocolName: 'Solid',
57 | },
58 | }[item],
59 | });
60 | }, {});
61 | },
62 |
63 | };
64 |
65 | Object.assign(exports, mod);
66 |
--------------------------------------------------------------------------------
/os-app/_shared/common/controller.js:
--------------------------------------------------------------------------------
1 | exports.OLSKControllerSharedStaticAssetFolders = function () {
2 | return [
3 | '_shared/__external',
4 | ];
5 | };
6 |
--------------------------------------------------------------------------------
/os-app/_shared/common/ui-style.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --OLSKCommonBackground: #f4f1e3;
3 | --OLSKDecorBackgroundDeep: var(--OLSKCommonBackground);
4 | --OLSKCommonForeground: #131037;
5 | }
6 |
7 | html, body, .OLSKDecorCapped {
8 | min-height: 100vh;
9 | }
10 |
--------------------------------------------------------------------------------
/os-app/api-projects/controller-tests.js:
--------------------------------------------------------------------------------
1 | const { throws, rejects, deepEqual } = require('assert');
2 |
3 | const mod = require('./controller.js');
4 |
5 | const { JSDOM } = require('jsdom');
6 | const OLSKLink = require('OLSKLink');
7 | const OLSKCache = require('OLSKCache');
8 | const ZDABank = require('../_shared/ZDABank/main.js');
9 |
10 | const uProject = function (inputData = {}) {
11 | return Object.assign({
12 | ZDAProjectBlurb: Math.random().toString(),
13 | ZDAProjectIconURL: Math.random().toString(),
14 | ZDAProjectHasManifest: true,
15 | }, inputData);
16 | };
17 |
18 | describe('DataProjectsSort', function test_DataProjectsSort() {
19 |
20 | it('bumps ZDAProjectIconURL', function () {
21 | const item1 = {};
22 | const item2 = {
23 | ZDAProjectIconURL: Math.random().toString(),
24 | };
25 |
26 | deepEqual([item1, item2].sort(mod.DataProjectsSort), [item2, item1]);
27 | });
28 |
29 | it('bumps ZDAProjectIconURL + ZDAProjectBlurb', function () {
30 | const item1 = {
31 | ZDAProjectIconURL: Math.random().toString(),
32 | };
33 | const item2 = {
34 | ZDAProjectBlurb: Math.random().toString(),
35 | ZDAProjectIconURL: Math.random().toString(),
36 | };
37 |
38 | deepEqual([item1, item2].sort(mod.DataProjectsSort), [item2, item1]);
39 | });
40 |
41 | it('bumps ZDAProjectHasManifest', function () {
42 | const item1 = {
43 | ZDAProjectBlurb: Math.random().toString(),
44 | ZDAProjectIconURL: Math.random().toString(),
45 | ZDAProjectHasManifest: false,
46 | };
47 | const item2 = {
48 | ZDAProjectBlurb: Math.random().toString(),
49 | ZDAProjectIconURL: Math.random().toString(),
50 | ZDAProjectHasManifest: true,
51 | };
52 |
53 | deepEqual([item1, item2].sort(mod.DataProjectsSort), [item2, item1]);
54 | });
55 |
56 | it('bumps ZDABankProtocol', function () {
57 | const item1 = {
58 | ZDAProjectBlurb: Math.random().toString(),
59 | ZDAProjectIconURL: Math.random().toString(),
60 | ZDAProjectHasManifest: true,
61 | ZDAProjectBanks: {
62 | [Math.random().toString()]: {},
63 | },
64 | };
65 | const item2 = {
66 | ZDAProjectBlurb: Math.random().toString(),
67 | ZDAProjectIconURL: Math.random().toString(),
68 | ZDAProjectHasManifest: true,
69 | ZDAProjectBanks: {
70 | [Math.random().toString()]: {
71 | ZDABankProtocol: {}
72 | },
73 | },
74 | };
75 |
76 | deepEqual([item1, item2].sort(mod.DataProjectsSort), [item2, item1]);
77 | });
78 |
79 | it('bumps blurb under 140 characters', function () {
80 | const item1 = {
81 | ZDAProjectBlurb: Array.from(Array(140 + uRandomInt())).map(function () {
82 | return 'x';
83 | }).join(''),
84 | ZDAProjectIconURL: Math.random().toString(),
85 | ZDAProjectHasManifest: true,
86 | ZDAProjectBanks: {
87 | [Math.random().toString()]: {},
88 | },
89 | };
90 | const item2 = {
91 | ZDAProjectBlurb: Array.from(Array(uRandomInt(140))).map(function () {
92 | return 'x';
93 | }).join(''),
94 | ZDAProjectIconURL: Math.random().toString(),
95 | ZDAProjectHasManifest: true,
96 | ZDAProjectBanks: {
97 | [Math.random().toString()]: {},
98 | },
99 | };
100 |
101 | deepEqual([item1, item2].sort(mod.DataProjectsSort), [item2, item1]);
102 | });
103 |
104 | it('bumps if not git', function () {
105 | const item1 = uProject({
106 | ZDAProjectURL: 'git' + Math.random().toString(),
107 | });
108 | const item2 = uProject({
109 | ZDAProjectURL: Math.random().toString(),
110 | });
111 |
112 | deepEqual([item1, item2].sort(mod.DataProjectsSort), [item2, item1]);
113 | });
114 |
115 | it('bumps github.io', function () {
116 | const item1 = uProject({
117 | ZDAProjectURL: 'git' + Math.random().toString(),
118 | });
119 | const item2 = uProject({
120 | ZDAProjectURL: 'github.io' + Math.random().toString(),
121 | });
122 |
123 | deepEqual([item1, item2].sort(mod.DataProjectsSort), [item2, item1]);
124 | });
125 |
126 | it('bumps gitea', function () {
127 | const item1 = uProject({
128 | ZDAProjectURL: 'git' + Math.random().toString(),
129 | });
130 | const item2 = uProject({
131 | ZDAProjectURL: 'gitea' + Math.random().toString(),
132 | });
133 |
134 | deepEqual([item1, item2].sort(mod.DataProjectsSort), [item2, item1]);
135 | });
136 |
137 | it('bumps pages.github.com', function () {
138 | const item1 = uProject({
139 | ZDAProjectURL: 'git' + Math.random().toString(),
140 | });
141 | const item2 = uProject({
142 | ZDAProjectURL: 'pages.github.com' + Math.random().toString(),
143 | });
144 |
145 | deepEqual([item1, item2].sort(mod.DataProjectsSort), [item2, item1]);
146 | });
147 |
148 | it('bumps about.gitlab.com', function () {
149 | const item1 = uProject({
150 | ZDAProjectURL: 'git' + Math.random().toString(),
151 | });
152 | const item2 = uProject({
153 | ZDAProjectURL: 'about.gitlab.com' + Math.random().toString(),
154 | });
155 |
156 | deepEqual([item1, item2].sort(mod.DataProjectsSort), [item2, item1]);
157 | });
158 |
159 | });
160 |
161 | describe('_DataProjectImageProperty', function test__DataProjectImageProperty() {
162 |
163 | const __DataProjectImageProperty = function (inputData = {}) {
164 | return Object.assign(Object.assign({}, mod), {
165 | }, inputData)._DataProjectImageProperty(inputData.ParamProject);
166 | };
167 |
168 | it('returns inputData', function () {
169 | const ParamProject = {
170 | ZDAProjectIconURL: uLink(),
171 | };
172 | deepEqual(__DataProjectImageProperty({
173 | ParamProject,
174 | }), ParamProject);
175 | });
176 |
177 | it('sets _ZDAProjectIconURLCachedPath if _DataFoilImages.DataCacheLocalPath', function () {
178 | const ZDAProjectIconURL = Math.random().toString();
179 | const DataCacheLocalPath = Math.random().toString();
180 |
181 | deepEqual(__DataProjectImageProperty({
182 | ParamProject: {
183 | ZDAProjectIconURL,
184 | },
185 | _DataFoilImages: {
186 | DataCacheLocalPath: (function () {
187 | return DataCacheLocalPath;
188 | }),
189 | },
190 | }), {
191 | ZDAProjectIconURL,
192 | _ZDAProjectIconURLCachedPath: DataCacheLocalPath,
193 | });
194 | });
195 |
196 | });
197 |
198 | describe('_DataProjectProperties', function test__DataProjectProperties() {
199 |
200 | const __DataProjectProperties = function (inputData = {}) {
201 | return Object.assign(Object.assign({}, mod), {
202 | _DataFoilDetails: {
203 | ValueCandidatesCache: function () {
204 | return inputData._ValueCandidatesCache || {};
205 | },
206 | },
207 | _DataDetailsDOMPropertyCandidates: (function () {
208 | return [];
209 | }),
210 | }, inputData)._DataProjectProperties(inputData.ParamProject);
211 | };
212 |
213 | it('throws if not object', function () {
214 | throws(function () {
215 | mod._DataProjectProperties(null);
216 | }, /ZDRErrorInputNotValid/);
217 | });
218 |
219 | it('returns inputData', function () {
220 | const ParamProject = {
221 | ZDAProjectURL: Math.random().toString(),
222 | };
223 | deepEqual(__DataProjectProperties({
224 | ParamProject,
225 | }), ParamProject);
226 | });
227 |
228 | it('includes _ValueCandidatesCache', function () {
229 | const ZDAProjectURL = Math.random().toString();
230 | const ParamProject = {
231 | ZDAProjectURL,
232 | };
233 | const _ValueCandidatesCache = {
234 | [ZDAProjectURL]: {
235 | [Math.random().toString()]: Math.random().toString(),
236 | },
237 | };
238 |
239 | deepEqual(__DataProjectProperties({
240 | ParamProject,
241 | _ValueCandidatesCache,
242 | }), Object.assign(ParamProject, _ValueCandidatesCache));
243 | });
244 |
245 | it('excludes underscore if present', function () {
246 | const ZDAProjectURL = Math.random().toString();
247 | const item = Math.random().toString();
248 | const ParamProject = {
249 | ZDAProjectURL,
250 | [item]: Math.random().toString(),
251 | };
252 | const _ValueCandidatesCache = {
253 | [ZDAProjectURL]: {
254 | ['_' + item]: Math.random().toString(),
255 | },
256 | };
257 |
258 | deepEqual(__DataProjectProperties({
259 | ParamProject,
260 | _ValueCandidatesCache,
261 | }), ParamProject);
262 | });
263 |
264 | it('strips underscore', function () {
265 | const ZDAProjectURL = Math.random().toString();
266 | const item = Math.random().toString();
267 | const ParamProject = {
268 | ZDAProjectURL,
269 | };
270 | const _ValueCandidatesCache = {
271 | [ZDAProjectURL]: {
272 | ['_' + item]: item,
273 | },
274 | };
275 |
276 | deepEqual(__DataProjectProperties({
277 | ParamProject,
278 | _ValueCandidatesCache,
279 | }), Object.assign(ParamProject, {
280 | [item]: item,
281 | }));
282 | });
283 |
284 | });
285 |
286 | describe('DataProjects', function test_DataProjects() {
287 |
288 | const _DataProjects = function (inputData = {}) {
289 | return Object.assign(Object.assign({}, mod), {
290 | _DataFoilDetails: Object.assign({
291 | ValueCandidatesCache: function () {
292 | return inputData._ValueCandidatesCache || {};
293 | },
294 | }, inputData),
295 | _DataFoilBanks: Object.assign({
296 | DataBankProjects: (function () {}),
297 | }, inputData),
298 | }, inputData).DataProjects();
299 | };
300 |
301 | it('merges sources', function () {
302 | const candidates = {
303 | [Math.random().toString()]: Math.random().toString(),
304 | };
305 | const ZDAProjectURL = Math.random().toString();
306 | const _ZDAProjectIconURLCachedPath = Math.random().toString();
307 | deepEqual(_DataProjects({
308 | _ValueCandidatesCache: {
309 | [ZDAProjectURL]: candidates,
310 | },
311 | DataBankProjects: (function () {
312 | return [{
313 | ZDAProjectURL,
314 | }];
315 | }),
316 | _DataProjectImageProperty: (function (inputData) {
317 | return Object.assign(inputData, {
318 | _ZDAProjectIconURLCachedPath,
319 | });
320 | }),
321 | }), [Object.assign({
322 | ZDAProjectURL,
323 | }, candidates, {
324 | _ZDAProjectIconURLCachedPath,
325 | })]);
326 | });
327 |
328 | it('sorts with DataProjectsSort', function () {
329 | const item1 = {
330 | ZDAProjectURL: Math.random().toString(),
331 | };
332 | const item2 = {
333 | ZDAProjectURL: Math.random().toString(),
334 | ZDAProjectIconURL: uLink(),
335 | };
336 |
337 | deepEqual(_DataProjects({
338 | DataBankProjects: (function () {
339 | return [item1, item2];
340 | }),
341 | }), [item2, item1]);
342 | });
343 |
344 | });
345 |
346 | describe('DataProjectJSONSchema', function test_DataProjectJSONSchema() {
347 |
348 | it('throws if not object', function () {
349 | throws(function () {
350 | mod.DataProjectJSONSchema(null);
351 | }, /ZDAErrorInputNotValid/);
352 | });
353 |
354 | it('returns object', function () {
355 | deepEqual(mod.DataProjectJSONSchema({}), {});
356 | });
357 |
358 | it('maps ZDAProjectName', function () {
359 | const item = Math.random().toString();
360 | deepEqual(mod.DataProjectJSONSchema({
361 | ZDAProjectName: item,
362 | }), {
363 | name: item,
364 | });
365 | });
366 |
367 | it('maps ZDAProjectBlurb', function () {
368 | const item = Math.random().toString();
369 | deepEqual(mod.DataProjectJSONSchema({
370 | ZDAProjectBlurb: item,
371 | }), {
372 | description: item,
373 | });
374 | });
375 |
376 | it('maps ZDAProjectURL', function () {
377 | const item = Math.random().toString();
378 | deepEqual(mod.DataProjectJSONSchema({
379 | ZDAProjectURL: item,
380 | }), {
381 | url: item,
382 | });
383 | });
384 |
385 | it('maps ZDAProjectIconURL', function () {
386 | const item = Math.random().toString();
387 | deepEqual(mod.DataProjectJSONSchema({
388 | ZDAProjectIconURL: item,
389 | }), {
390 | image: item,
391 | });
392 | });
393 |
394 | it('maps ZDAProjectFunding', function () {
395 | const item = Math.random().toString();
396 | deepEqual(mod.DataProjectJSONSchema({
397 | ZDAProjectFunding: item,
398 | }), {
399 | funding: item,
400 | });
401 | });
402 |
403 | context('ZDAProjectBanks', function () {
404 |
405 | it('maps ZDAProtocolName', function () {
406 | deepEqual(mod.DataProjectJSONSchema({
407 | ZDAProjectBanks: {
408 | [Math.random().toString()]: {
409 | ZDABankProtocol: {},
410 | },
411 | },
412 | }), {
413 | protocols: [],
414 | });
415 | });
416 |
417 | it('lowercases name', function () {
418 | const items = Array.from(Array(Math.max(1, uRandomInt(10)))).map(function () {
419 | return 'ALFA' + Math.random().toString();
420 | });
421 | deepEqual(mod.DataProjectJSONSchema({
422 | ZDAProjectBanks: items.reduce(function (coll, ZDAProtocolName) {
423 | return Object.assign(coll, {
424 | [Math.random().toString()]: {
425 | ZDABankProtocol: {
426 | ZDAProtocolName,
427 | },
428 | },
429 | });
430 | }, {}),
431 | }), {
432 | protocols: items.map(function (e) {
433 | return e.toLowerCase();
434 | }),
435 | });
436 | });
437 |
438 | });
439 |
440 | });
441 |
442 | describe('DataProjectsJSON', function test_DataProjectsJSON() {
443 |
444 | it('returns array', function () {
445 | const ZDAProjectName = Math.random().toString();
446 | const item = {
447 | ZDAProjectName,
448 | };
449 |
450 | deepEqual(Object.assign(Object.assign({}, mod), {
451 | DataProjects: (function () {
452 | return [item];
453 | }),
454 | }).DataProjectsJSON(), [mod.DataProjectJSONSchema(item)]);
455 | });
456 |
457 | });
458 |
--------------------------------------------------------------------------------
/os-app/api-projects/controller.js:
--------------------------------------------------------------------------------
1 | const uAscending = function (a, b) {
2 | return (a < b) ? -1 : ((a > b) ? 1 : 0);
3 | };
4 |
5 | const uDescending = function (a, b) {
6 | return (a > b) ? -1 : ((a < b) ? 1 : 0);
7 | };
8 |
9 | const mod = {
10 |
11 | OLSKControllerRoutes () {
12 | return [{
13 | OLSKRoutePath: '/projects.json',
14 | OLSKRouteMethod: 'get',
15 | OLSKRouteSignature: 'ZDAProjectsJSONRoute',
16 | OLSKRouteFunction: (function ZDAProjectsJSONRoute (req, res, next) {
17 | return res.json(mod.DataProjectsJSON());
18 | }),
19 | }];
20 | },
21 |
22 | // DATA
23 |
24 | _DataFoilBanks: require('../task-a-banks/controller.js'),
25 | _DataFoilDetails: require('../task-b-details/controller.js'),
26 | _DataFoilImages: require('../task-c-images/controller.js'),
27 |
28 | DataProjectsSort (a, b) {
29 | const unmatched = [
30 | 'ZDAProjectIconURL',
31 | 'ZDAProjectBlurb',
32 | 'ZDAProjectHasManifest',
33 | ].filter(function (e) {
34 | return !a[e] || !b[e];
35 | });
36 |
37 | if (unmatched.length) {
38 | return uDescending(unmatched.reduce(function (coll, item) {
39 | return coll + !!a[item];
40 | }, 0), unmatched.reduce(function (coll, item) {
41 | return coll + !!b[item];
42 | }, 0));
43 | }
44 |
45 | if (a.ZDAProjectBlurb.length > 140 || b.ZDAProjectBlurb.length > 140) {
46 | return uAscending(a.ZDAProjectBlurb.length, b.ZDAProjectBlurb.length);
47 | }
48 |
49 | const pattern = /git(?!hub.io)(?!ea)/i;
50 | const exclude = /(pages.github.com|about.gitlab.com)/i;
51 | if (a.ZDAProjectURL?.match(pattern) || b.ZDAProjectURL?.match(pattern)) {
52 | return uAscending(a.ZDAProjectURL?.match(pattern) && !a.ZDAProjectURL?.match(exclude), b.ZDAProjectURL?.match(pattern) && !b.ZDAProjectURL?.match(exclude));
53 | }
54 |
55 | return uDescending(...[a, b].map(function (e) {
56 | return Object.values(e.ZDAProjectBanks || {}).filter(function (e) {
57 | return e.ZDABankProtocol;
58 | }).length;
59 | }));
60 | },
61 |
62 | _DataProjectImageProperty (inputData) {
63 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
64 |
65 | if (inputData.ZDAProjectIconURL) {
66 | inputData._ZDAProjectIconURLCachedPath = _mod._DataFoilImages.DataCacheLocalPath(inputData.ZDAProjectIconURL);
67 | }
68 |
69 | return inputData;
70 | },
71 |
72 | _DataProjectProperties (inputData) {
73 | if (typeof inputData !== 'object' || inputData === null) {
74 | throw new Error('ZDRErrorInputNotValid');
75 | }
76 |
77 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
78 |
79 | return Object.entries(_mod._DataFoilDetails.ValueCandidatesCache()[inputData.ZDAProjectURL] || {}).reduce(function (coll, [key, value]) {
80 | if (key.startsWith('_') && coll[key.slice(1)]) {
81 | return coll;
82 | }
83 |
84 | if (key.startsWith('_')) {
85 | key = key.slice(1);
86 | }
87 |
88 | return Object.assign(coll, {
89 | [key]: value,
90 | });
91 | }, inputData);
92 | },
93 |
94 | DataProjects () {
95 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
96 |
97 | // require('OLSKDisk').OLSKDiskWrite(require('OLSKDisk').OLSKDiskOpen(require('OLSKCache').OLSKCachePath(__dirname, '1-banks.json')), JSON.stringify(_mod._DataFoilBanks.DataBankProjects(), null, ' '));
98 | // require('OLSKDisk').OLSKDiskWrite(require('OLSKDisk').OLSKDiskOpen(require('OLSKCache').OLSKCachePath(__dirname, '2-details.json')), JSON.stringify(_mod._DataFoilBanks.DataBankProjects().map(function (e) { return _mod._DataProjectProperties(e) }), null, ' '));
99 |
100 | return _mod._DataFoilBanks.DataBankProjects().map(function (e) {
101 | return _mod._DataProjectProperties(e);
102 | }).map(function (e) {
103 | return _mod._DataProjectImageProperty(e);
104 | }).sort(mod.DataProjectsSort);
105 | },
106 |
107 | DataProjectJSONSchema (inputData) {
108 | if (typeof inputData !== 'object' || inputData === null) {
109 | throw new Error('ZDAErrorInputNotValid');
110 | }
111 |
112 | return Object.entries({
113 | ZDAProjectName: 'name',
114 | ZDAProjectBlurb: 'description',
115 | ZDAProjectURL: 'url',
116 | ZDAProjectIconURL: 'image',
117 | ZDAProjectBanks: 'protocols',
118 | ZDAProjectFunding: 'funding',
119 | }).reduce(function (coll, item) {
120 | return Object.assign(coll, !inputData[item[0]] ? {} : {
121 | [item[1]]: item[0] === 'ZDAProjectBanks' ? Object.values(inputData[item[0]]).filter(function (e) {
122 | return (e.ZDABankProtocol || {}).ZDAProtocolName;
123 | }).map(function (e) {
124 | return e.ZDABankProtocol.ZDAProtocolName.toLowerCase();
125 | }) : inputData[item[0]],
126 | });
127 | }, {});
128 | },
129 |
130 | DataProjectsJSON () {
131 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
132 |
133 | return _mod.DataProjects().map(mod.DataProjectJSONSchema);
134 | },
135 |
136 | };
137 |
138 | Object.assign(exports, mod);
139 |
--------------------------------------------------------------------------------
/os-app/open-glance/controller.js:
--------------------------------------------------------------------------------
1 | const projects = require('../api-projects/controller.js');
2 |
3 | const mod = {
4 |
5 | OLSKControllerRoutes () {
6 | return [{
7 | OLSKRoutePath: '/glance',
8 | OLSKRouteMethod: 'get',
9 | OLSKRouteSignature: 'ZDAGlanceRoute',
10 | OLSKRouteFunction: (function ZDAGlanceRoute (req, res, next) {
11 | return res.OLSKExpressLayoutRender(require('path').join(__dirname, 'ui-view'), res.locals.OLSK_SPEC_UI() ? Object.assign({
12 | ZDAGlanceListData: [{
13 | ZDAProjectBanks: {},
14 | }],
15 | }, Object.fromEntries(Array.from((new URLSearchParams(req.query)).entries()).map(function (e) {
16 | if (e[0] === 'ZDAGlanceListData') {
17 | e[1] = JSON.parse(e[1]);
18 | }
19 |
20 | return e;
21 | }))) : {
22 | ZDAGlanceListData: projects.DataProjects(),
23 | });
24 | }),
25 | OLSKRouteLanguageCodes: ['en'],
26 | }];
27 | },
28 |
29 | };
30 |
31 | Object.assign(exports, mod);
32 |
--------------------------------------------------------------------------------
/os-app/open-glance/i18n-en.yml:
--------------------------------------------------------------------------------
1 | ZDAGlanceFilterInputText: Type to filter
2 |
--------------------------------------------------------------------------------
/os-app/open-glance/ui-behaviour.js:
--------------------------------------------------------------------------------
1 | const mod = {
2 |
3 | // CONTROL
4 |
5 | ControlSearch (inputData) {
6 | mod._ValueList.search(inputData);
7 | document.querySelector('.ZDAGlanceFilterInput').value = inputData;
8 | },
9 |
10 | // LIFECYCLE
11 |
12 | LifecyclePageWillLoad() {
13 | mod._ValueList = new List(document.querySelector('.ZDAGlance'), {
14 | searchClass: 'ZDAGlanceFilterInput',
15 | sortClass: 'ZDAGlanceListSort',
16 | valueNames: [
17 | 'ZDAGlanceListItemName',
18 | 'ZDAGlanceListItemBlurb',
19 | { data: ['protocols'] },
20 | ],
21 | });
22 | },
23 |
24 | };
25 |
--------------------------------------------------------------------------------
/os-app/open-glance/ui-style.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --ZDAGlanceToolbarHeight: 0;
3 | --OLSKStickyHeaderTop: var(--ZDAGlanceToolbarHeight);
4 | }
5 |
6 | @media screen and (max-width: 760px) {
7 |
8 | :root {
9 | --ZDAGlanceToolbarHeight: 80px;
10 | }
11 |
12 | }
13 |
14 | .ZDAGlance {
15 | padding: 0;
16 | padding-top: calc(var(--ZDAGlanceToolbarHeight) + 1px);
17 |
18 | font-family: Arial;
19 | font-size: 9pt;
20 | }
21 |
22 | .ZDAGlanceHeader div {
23 | display: flex !important;
24 |
25 | background: var(--OLSKCommonBackground);
26 |
27 | align-items: center;
28 | }
29 |
30 | .ZDAGlanceHeaderTwo {
31 | padding: 5px;
32 | }
33 |
34 | .ZDAGlanceHeaderTwo * {
35 | margin-right: 4px;
36 | }
37 |
38 | .ZDAGlanceRootLink {
39 | line-height: 0;
40 | }
41 |
42 | .ZDAGlanceRootLinkImage {
43 | width: 32px;
44 | padding: 4px;
45 | }
46 |
47 | @media screen and (max-width: 760px) {
48 |
49 | .ZDAGlanceRootLinkImage {
50 | width: 36px;
51 | }
52 |
53 | }
54 |
55 | .ZDAGlanceListSort {
56 | cursor: pointer;
57 | }
58 |
59 | .ZDAGlanceListSort:after {
60 | width: 0;
61 | height: 0;
62 | border-left: 5px solid transparent;
63 | border-right: 5px solid transparent;
64 | content: "";
65 | position: relative;
66 | }
67 |
68 | .ZDAGlanceListSort.asc:after {
69 | border-bottom: 5px solid #000;
70 | top: -10px;
71 | right: -5px;
72 | }
73 |
74 | .ZDAGlanceListSort.desc:after {
75 | border-top: 5px solid #000;
76 | top: 10px;
77 | right:-5px;
78 | }
79 |
80 | .ZDAGlanceFilterInput {
81 | padding: 5px 8px !important;
82 | height: 100%;
83 | border: none !important;
84 | border-radius: 5px !important;
85 | flex-grow: 1;
86 |
87 | background: #e3e0d4 !important;
88 | font-size: 125%;
89 | }
90 |
91 | @media screen and (max-width: 760px) {
92 |
93 | .ZDAGlanceFilterInput {
94 | font-size: 120%;
95 | }
96 |
97 | }
98 |
99 | .ZDAGlanceProjectsCompilationLink {
100 | padding: 0 10px;
101 | }
102 |
103 | .ZDAGlanceList .list {
104 | display: flex;
105 | flex-wrap: wrap;
106 | justify-content: center;
107 | }
108 |
109 | .ZDAGlanceListItem {
110 | padding: 10px;
111 | width: 220px;
112 |
113 | font-size: 120%;
114 | }
115 |
116 | @media screen and (max-width: 760px) {
117 |
118 | .ZDAGlanceListItem {
119 | width: 100%;
120 | padding: unset;
121 |
122 | font-size: 100%;
123 | }
124 |
125 | }
126 |
127 | .ZDAGlanceListItemIconImage {
128 | width: 100%;
129 | padding: 10px;
130 | border-radius: 15px;
131 |
132 | margin: 0 !important;
133 | }
134 |
135 | @media screen and (max-width: 760px) {
136 |
137 | .ZDAGlanceListItemIconImage {
138 | --OLSKCommonCardImageSize: 48px !important;
139 | }
140 |
141 | }
142 |
143 | .ZDAGlanceListItemName {
144 | font-size: 140%;
145 | text-decoration: none;
146 | }
147 |
148 | .ZDAGlanceListItemBlurb {
149 | opacity: 0.5;
150 | }
151 |
--------------------------------------------------------------------------------
/os-app/open-glance/ui-test-_access.js:
--------------------------------------------------------------------------------
1 | const kDefaultRoute = require('./controller.js').OLSKControllerRoutes().shift();
2 |
3 | Object.entries({
4 | ZDAGlance: '.ZDAGlance',
5 |
6 | ZDAGlanceHeader: '.ZDAGlanceHeader',
7 | ZDAGlanceHeaderOne: '.ZDAGlanceHeaderOne',
8 | ZDAGlanceHeaderTwo: '.ZDAGlanceHeaderTwo',
9 |
10 | ZDAGlanceRootLink: '.ZDAGlanceRootLink',
11 | ZDAGlanceRootLinkImage: '.ZDAGlanceRootLinkImage',
12 |
13 | ZDAGlanceFilterInput: '.ZDAGlanceFilterInput',
14 |
15 | ZDAGlanceProjectsCompilationLink: '.ZDAGlanceProjectsCompilationLink',
16 |
17 | ZDAGlanceProtocolButton: '.ZDAGlanceProtocolButton',
18 | }).map(function (e) {
19 | return global[e.shift()] = e.pop();
20 | });
21 |
22 | describe('ZDAGlance_Access', function () {
23 |
24 | const count = uRandomInt(10);
25 |
26 | const banks = Array.from(Array(count + 1)).map(function () {
27 | return [Math.random().toString(), {
28 | ZDABankProtocol: {
29 | ZDAProtocolName: Math.random().toString()
30 | },
31 | }];
32 | });
33 |
34 | before(function () {
35 | return browser.OLSKVisit(kDefaultRoute, {
36 | ZDAGlanceListData: JSON.stringify(Array.from(Array(uRandomInt(10))).map(function (e, i) {
37 | return {
38 | ZDAProjectName: Math.random().toString(),
39 | ZDAProjectBanks: Object.fromEntries(banks.slice(1)),
40 | };
41 | })),
42 | });
43 | });
44 |
45 | it('shows ZDAGlance', function() {
46 | return browser.assert.elements(ZDAGlance, 1);
47 | });
48 |
49 | it('shows ZDAGlanceHeader', function () {
50 | return browser.assert.elements(ZDAGlanceHeader, 1);
51 | });
52 |
53 | it('shows ZDAGlanceHeaderOne', function () {
54 | return browser.assert.elements(ZDAGlanceHeaderOne, 1);
55 | });
56 |
57 | it('shows ZDAGlanceHeaderTwo', function () {
58 | return browser.assert.elements(ZDAGlanceHeaderTwo, 1);
59 | });
60 |
61 | it('shows ZDAGlanceRootLink', function () {
62 | return browser.assert.elements(ZDAGlanceRootLink, 1);
63 | });
64 |
65 | it('shows ZDAGlanceRootLinkImage', function () {
66 | return browser.assert.elements(ZDAGlanceRootLinkImage, 1);
67 | });
68 |
69 | it('shows ZDAGlanceFilterInput', function () {
70 | return browser.assert.elements(ZDAGlanceFilterInput, 1);
71 | });
72 |
73 | it('shows ZDAGlanceProjectsCompilationLink', function () {
74 | return browser.assert.elements(ZDAGlanceProjectsCompilationLink, 1);
75 | });
76 |
77 | it('shows ZDAGlanceProtocolButton', function () {
78 | return browser.assert.elements(ZDAGlanceProtocolButton, count);
79 | });
80 |
81 | });
82 |
--------------------------------------------------------------------------------
/os-app/open-glance/ui-test-_localize.js:
--------------------------------------------------------------------------------
1 | const kDefaultRoute = require('./controller.js').OLSKControllerRoutes().shift();
2 |
3 | kDefaultRoute.OLSKRouteLanguageCodes.forEach(function (OLSKRoutingLanguage) {
4 |
5 | const uLocalized = function (inputData) {
6 | return OLSKTestingLocalized(inputData, OLSKRoutingLanguage);
7 | };
8 |
9 | describe('ZDAGlance_Localize-' + OLSKRoutingLanguage, function () {
10 |
11 | before(function() {
12 | return browser.OLSKVisit(kDefaultRoute, {
13 | OLSKRoutingLanguage,
14 | });
15 | });
16 |
17 | it('localizes title', function() {
18 | return browser.assert.text('title', uLocalized('ZDAVitrineTitle'));
19 | });
20 |
21 | it('localizes meta[description]', function() {
22 | return browser.assert.attribute('meta[name=description]', 'content', uLocalized('ZDAVitrineDescription'));
23 | });
24 |
25 | it('localizes ZDAGlanceRootLink', function () {
26 | return browser.assert.attribute(ZDAGlanceRootLink, 'title', uLocalized('OLSKRootLinkTextHome'));
27 | });
28 |
29 | it('localizes ZDAGlanceFilterInput', function () {
30 | return browser.assert.attribute(ZDAGlanceFilterInput, 'placeholder', uLocalized('ZDAGlanceFilterInputText'));
31 | });
32 |
33 | });
34 |
35 | });
36 |
--------------------------------------------------------------------------------
/os-app/open-glance/ui-test-_misc.js:
--------------------------------------------------------------------------------
1 | const kDefaultRoute = require('./controller.js').OLSKControllerRoutes().shift();
2 |
3 | describe('ZDAGlance_Misc', function () {
4 |
5 | const count = Math.min(2, uRandomInt(10));
6 |
7 | const item = {
8 | ZDAProjectName: Math.random().toString(),
9 | };
10 |
11 | const banks = Array.from(Array(uRandomInt(3))).map(function () {
12 | return [Math.random().toString(), {
13 | ZDABankProtocol: {
14 | ZDAProtocolName: Math.random().toString()
15 | },
16 | }];
17 | });
18 |
19 | before(function () {
20 | return browser.OLSKVisit(kDefaultRoute, {
21 | ZDAGlanceListData: JSON.stringify(Array.from(Array(count)).map(function (e, i) {
22 | return Object.assign(i ? {
23 | ZDAProjectName: Math.random().toString(),
24 | } : item, {
25 | ZDAProjectBlurb: i.toString(),
26 | }, {
27 | ZDAProjectBanks: Object.fromEntries(banks),
28 | });
29 | })),
30 | });
31 | });
32 |
33 | it('sets meta:viewport', function () {
34 | return browser.assert.attribute('meta[name=viewport]', 'content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0');
35 | });
36 |
37 | describe('ZDAGlance', function () {
38 |
39 | it('classes OLSKDecor', function () {
40 | return browser.assert.hasClass(ZDAGlance, 'OLSKDecor');
41 | });
42 |
43 | });
44 |
45 | describe('ZDAGlanceHeader', function test_ZDAGlanceHeader () {
46 |
47 | it('classes OLSKDecorFixedHeader', function () {
48 | return browser.assert.hasClass(ZDAGlanceHeader, 'OLSKDecorFixedHeader');
49 | });
50 |
51 | });
52 |
53 | describe('ZDAGlanceHeaderOne', function test_ZDAGlanceHeaderOne () {
54 |
55 | it('classes OLSKCommonEdgeBottom', function () {
56 | return browser.assert.hasClass(ZDAGlanceHeaderOne, 'OLSKCommonEdgeBottom');
57 | });
58 |
59 | });
60 |
61 | describe('ZDAGlanceHeaderTwo', function test_ZDAGlanceHeaderTwo () {
62 |
63 | it('classes OLSKCommonEdgeBottom', function () {
64 | return browser.assert.hasClass(ZDAGlanceHeaderTwo, 'OLSKCommonEdgeBottom');
65 | });
66 |
67 | it('classes OLSKDecorFormBlend', function () {
68 | return browser.assert.hasClass(ZDAGlanceHeaderTwo, 'OLSKDecorFormBlend');
69 | });
70 |
71 | });
72 |
73 | describe('ZDAGlanceRootLink', function test_ZDAGlanceRootLink () {
74 |
75 | it('sets href', function () {
76 | return browser.assert.attribute(ZDAGlanceRootLink, 'href', require('../open-vitrine/controller.js').OLSKControllerRoutes().shift().OLSKRoutePath);
77 | });
78 |
79 | });
80 |
81 | describe('ZDAGlanceRootLinkImage', function test_ZDAGlanceRootLinkImage () {
82 |
83 | it('sets src', function () {
84 | return browser.assert.attribute(ZDAGlanceRootLinkImage, 'src', process.env.ZDA_VITRINE_IDENTITY_URL);
85 | });
86 |
87 | });
88 |
89 | describe('ZDAGlanceFilterInput', function test_ZDAGlanceFilterInput () {
90 |
91 | it('sets type', function () {
92 | return browser.assert.attribute(ZDAGlanceFilterInput, 'type', 'search');
93 | });
94 |
95 | it('sets accesskey', function () {
96 | return browser.assert.attribute(ZDAGlanceFilterInput, 'accesskey', 'f');
97 | });
98 |
99 | it('classes OLSKDecorInput', function () {
100 | return browser.assert.hasClass(ZDAGlanceFilterInput, 'OLSKDecorInput');
101 | });
102 |
103 | context('input', function () {
104 |
105 | before(function () {
106 | return browser.assert.elements('.ZDAGlanceListItem', count);
107 | });
108 |
109 | before(function () {
110 | browser.fill(ZDAGlanceFilterInput, item.ZDAProjectName);
111 | });
112 |
113 | it.skip('filters list', function () {
114 | return browser.assert.elements('.ZDAGlanceListItem', 1);
115 | });
116 |
117 | });
118 |
119 | context('Escape', function () {
120 |
121 | before(function () {
122 | return browser.OLSKFireKeyboardEvent(browser.window, 'Escape');
123 | });
124 |
125 | it('filters list', function () {
126 | return browser.assert.elements('.ZDAGlanceListItem', count);
127 | });
128 |
129 | it('sets filter text', function () {
130 | return browser.assert.text(ZDAGlanceFilterInput, '');
131 | });
132 |
133 | });
134 |
135 | });
136 |
137 | describe('ZDAGlanceProjectsCompilationLink', function test_ZDAGlanceProjectsCompilationLink () {
138 |
139 | it('sets href', function () {
140 | return browser.assert.attribute(ZDAGlanceProjectsCompilationLink, 'href', require('../api-projects/controller.js').OLSKControllerRoutes().shift().OLSKRoutePath);
141 | });
142 |
143 | it('sets text', function () {
144 | return browser.assert.text(ZDAGlanceProjectsCompilationLink, 'JSON');
145 | });
146 |
147 | });
148 |
149 | banks.forEach(function (e, i) {
150 |
151 | let text = '';
152 |
153 | describe('ZDAGlanceProtocolButton', function test_ZDAGlanceProtocolButton () {
154 |
155 | const selector = `.ZDAGlanceProtocolButton:nth-child(${ i + 1 })`;
156 |
157 | it('binds ZDAProtocolName', function () {
158 | return browser.assert.text(selector, e[1].ZDABankProtocol.ZDAProtocolName);
159 | });
160 |
161 | context.skip('click', function () {
162 |
163 | before(function () {
164 | return browser.assert.input(ZDAGlanceFilterInput, text);
165 | });
166 |
167 | before(function () {
168 | browser.pressButton(selector, item.ZDAProjectName);
169 | });
170 |
171 | it('sets ZDAGlanceFilterInput text', function () {
172 | return browser.assert.input(ZDAGlanceFilterInput, e[1].ZDABankProtocol.ZDAProtocolName);
173 | });
174 |
175 | });
176 |
177 | });
178 |
179 | });
180 |
181 | });
182 |
--------------------------------------------------------------------------------
/os-app/open-glance/ui-view.ejs:
--------------------------------------------------------------------------------
1 | <%
2 | locals.OLSKPageTitle = OLSKLocalized('ZDAVitrineTitle');
3 | locals.OLSKPageCanonical = 'https://0data.app/glance';
4 | locals.OLSKPageDescription = OLSKLocalized('ZDAVitrineDescription');
5 | locals.OLSKPageAssets = [
6 | '/_shared/__external/normalize.css/normalize.css',
7 | '/_shared/__external/OLSKDecor/ui-style.css',
8 | '/_shared/__external/list.js/dist/list.min.js',
9 | '/_shared/common/ui-style.css',
10 | 'ui-behaviour.js',
11 | 'ui-style.css',
12 | ];
13 | locals.OLSKPageMetaViewport = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0';
14 | %>
15 |
16 |
17 |
18 |
40 |
41 | <%- include('../sub-list/ui-view.ejs') %>
42 |
43 |
44 |
45 |
48 |
--------------------------------------------------------------------------------
/os-app/open-vitrine/controller.js:
--------------------------------------------------------------------------------
1 | const mod = {
2 |
3 | OLSKControllerRoutes () {
4 | return [{
5 | OLSKRoutePath: '/',
6 | OLSKRouteMethod: 'get',
7 | OLSKRouteSignature: 'ZDAVitrineRoute',
8 | OLSKRouteFunction: (function ZDAVitrineRoute (req, res, next) {
9 | return res.OLSKExpressLayoutRender(require('path').join(__dirname, 'ui-view'));
10 | }),
11 | OLSKRouteLanguageCodes: ['en', 'fr', 'es', 'pt'],
12 | }];
13 | },
14 |
15 | };
16 |
17 | Object.assign(exports, mod);
18 |
--------------------------------------------------------------------------------
/os-app/open-vitrine/i18n-en.yml:
--------------------------------------------------------------------------------
1 | ZDAVitrineTitle: Zero Data App
2 | ZDAVitrineDescription: 'Own your data, all of it.'
3 | OLSKLandingBlurbText: Apps that let you control your data.
4 | OLSKLandingActionTextFormat: Browse %@ apps
5 | ZDAVitrinePrinciplesHeadingText: Principles
6 | ZDAVitrinePrinciplesListItemText:
7 | - an app in which your data stays with you
8 | - you control where the data is stored
9 | - 'no spam, no captcha, no sign up, no passwords, bring your own identity'
10 | - using open protocols for flexibility and interoperability
11 | - do what you want with your data at any time
12 | - your data is accessible forever even if the app stops working
13 | ZDAVitrineFlowsHeadingText: Flows
14 | ZDAVitrineFlowsTraditionalHeadingText: The traditional way.
15 | ZDAVitrineFlowsTraditionalBlurbText: 'Go ''through'' apps in order to access your data—without the app, you have no way to access what is yours.'
16 | ZDAVitrineFlowsModernHeadingText: The 0data way.
17 | ZDAVitrineFlowsModernBlurbText: Keep your data under your control at the start and give permission for apps to access it as necessary.
18 | ZDAVitrineProtocolsHeadingText: Protocols
19 | ZDAVitrineToolsHeadingText: Tools
20 | ZDAVitrineEventsHeadingText: Events
21 | ZDAVitrineGroupDiscussionHeadingText: Previously on 0data…
22 | ZDAVitrineReadingHeadingText: Get interop-pilled
23 | ZDAVitrineAdjacentHeadingText: Adjacent initiatives
24 | ZDAVitrineAlsoHeadingText: See also
25 | ZDAVitrineEasyIndieCrownBlurbText: Run your own X in a few clicks.
26 |
--------------------------------------------------------------------------------
/os-app/open-vitrine/i18n-es.yml:
--------------------------------------------------------------------------------
1 | ZDAVitrineTitle: Zero Data App
2 | ZDAVitrineDescription: 'Ser dueno de tus datos, todos ellos.'
3 | OLSKLandingBlurbText: Aplicaciones que te permiten controlar tus datos.
4 | OLSKLandingActionTextFormat: Mirar %@ apps
5 | ZDAVitrinePrinciplesHeadingText: Principios
6 | ZDAVitrinePrinciplesListItemText:
7 | - una aplicación en la que tus datos se quedan contigo
8 | - tu controlas donde se almacenan los datos
9 | - 'sin spam, sin captcha, sin cuenta, sin contraseña, trae tu propia identidad'
10 | - usando protocolos abiertos para flexibilidad e interoperabilidad
11 | - haga lo que quieras con tus datos en cualquier momento
12 | - tus datos son accesibles para siempre incluso si la aplicación deja de funcionar
13 | ZDAVitrineFlowsHeadingText: Flujos
14 | ZDAVitrineFlowsTraditionalHeadingText: El camino tradicional.
15 | ZDAVitrineFlowsTraditionalBlurbText: '''Atravesar'' aplicaciones para acceder a tus datos—sin la aplicación, no tienes como acceder a lo que es tuyo.'
16 | ZDAVitrineFlowsModernHeadingText: El camino 0data.
17 | ZDAVitrineFlowsModernBlurbText: Mantener tus datos bajo tu control al principio y dar permiso para aplicaciones acceder cuando sea necesario.
18 | ZDAVitrineProtocolsHeadingText: Protocolos
19 | ZDAVitrineToolsHeadingText: Herramientas
20 | ZDAVitrineEventsHeadingText: Eventos
21 | ZDAVitrineGroupDiscussionHeadingText: Anteriormente en 0data…
22 | ZDAVitrineReadingHeadingText: Lectura
23 | ZDAVitrineAdjacentHeadingText: Iniciativas adyacentes
24 | ZDAVitrineAlsoHeadingText: Ver también
25 | ZDAVitrineEasyIndieCrownBlurbText: Ejecutar tu proprio X en pocos clics.
26 |
--------------------------------------------------------------------------------
/os-app/open-vitrine/i18n-fr.yml:
--------------------------------------------------------------------------------
1 | ZDAVitrineTitle: Zero Data App
2 | ZDAVitrineDescription: 'Être propriétaire de vos données, tout.'
3 | OLSKLandingBlurbText: Des applications qui vous permettent de contrôler vos données.
4 | OLSKLandingActionTextFormat: Regarder %@ applications
5 | ZDAVitrinePrinciplesHeadingText: Principes
6 | ZDAVitrinePrinciplesListItemText:
7 | - une application dans laquelle vos données restent avec vous
8 | - vous contrôlez où les données sont stockées
9 | - 'Pas de spam, pas de captcha, pas d''inscription, pas de mots de passe, apportez votre propre identité'
10 | - utilisant des protocoles ouverts pour la flexibilité et l'interopérabilité
11 | - faites ce que vous voulez avec vos données à tout moment
12 | - vos données sont accessibles pour toujours même si l'application ne fonctionne plus
13 | ZDAVitrineFlowsHeadingText: Passages
14 | ZDAVitrineFlowsTraditionalHeadingText: La façon traditionnelle.
15 | ZDAVitrineFlowsTraditionalBlurbText: '''Traverser'' des applications pour accéder à vos données—sans l''application, il n''y a aucun moyen d''accéder à ce qui vous appartient.'
16 | ZDAVitrineFlowsModernHeadingText: La façon 0data.
17 | ZDAVitrineFlowsModernBlurbText: Garder nos données sous notre contrôle au départ et à autoriser les applications à y accéder quand cela sera nécessaire.
18 | ZDAVitrineProtocolsHeadingText: Les protocoles
19 | ZDAVitrineToolsHeadingText: Des outils
20 | ZDAVitrineEventsHeadingText: Des événements
21 | ZDAVitrineGroupDiscussionHeadingText: Antérieurement sur 0data…
22 | ZDAVitrineReadingHeadingText: Lecture
23 | ZDAVitrineAdjacentHeadingText: Initiatives adjacentes
24 | ZDAVitrineAlsoHeadingText: Voir aussi
25 | ZDAVitrineEasyIndieCrownBlurbText: Exécuter votre propre X avec peu de clic.
26 |
--------------------------------------------------------------------------------
/os-app/open-vitrine/i18n-pt.yml:
--------------------------------------------------------------------------------
1 | ZDAVitrineTitle: Zero Data App
2 | ZDAVitrineDescription: 'Ser dono dos seus dados, todos eles.'
3 | OLSKLandingBlurbText: Aplicativos que lhe permitem controlar seus dados.
4 | OLSKLandingActionTextFormat: Dar uma olhada em %@ aplicativos
5 | ZDAVitrinePrinciplesHeadingText: Princípios
6 | ZDAVitrinePrinciplesListItemText:
7 | - um aplicativo no qual os seus dados ficam com você
8 | - você controla onde os dados são armazenados
9 | - 'sem spam, sem captcha, sem conta, sem senha, traga sua própria identidade'
10 | - usando protocolos abertos para flexibilidade e interoperabilidade
11 | - faça o que você quer com seus dados em qualquer momento
12 | - seus dados são acessíveis para sempre mesmo qua o aplicativo deixe de funcionar
13 | ZDAVitrineFlowsHeadingText: Fluxos
14 | ZDAVitrineFlowsTraditionalHeadingText: O jeito tradicional.
15 | ZDAVitrineFlowsTraditionalBlurbText: '''Atravessar'' aplicativos para acessar seus dados—sem o aplicativo, você não tem como acessar o que é seu.'
16 | ZDAVitrineFlowsModernHeadingText: O jeito 0data.
17 | ZDAVitrineFlowsModernBlurbText: Manter seus dados sob seu controle no início e dar permissão para aplicativos acessar quando necessário.
18 | ZDAVitrineProtocolsHeadingText: Protocolos
19 | ZDAVitrineToolsHeadingText: Ferramentas
20 | ZDAVitrineEventsHeadingText: Eventos
21 | ZDAVitrineGroupDiscussionHeadingText: Anteriormente em 0data…
22 | ZDAVitrineReadingHeadingText: Leitura
23 | ZDAVitrineAdjacentHeadingText: Iniciativas adjacentes
24 | ZDAVitrineAlsoHeadingText: Ver também
25 | ZDAVitrineEasyIndieCrownBlurbText: Executar seu próprio X em poucos cliques.
26 |
--------------------------------------------------------------------------------
/os-app/open-vitrine/ui-style.css:
--------------------------------------------------------------------------------
1 | .ZDAVitrinePrinciplesList {
2 | padding-left: 0 !important;
3 | text-indent: 0;
4 | list-style: none;
5 | }
6 |
7 | .ZDAVitrinePrinciplesListItem {
8 | padding: 10px;
9 | border-radius: 5px;
10 |
11 | margin: 10px 0;
12 |
13 | background: #e3e0d4;
14 | }
15 |
16 | .ZDAVitrinePrinciplesListItem em {
17 | font-weight: bold;
18 | font-style: normal;
19 | }
20 |
21 | .ZDAVitrineFlowsItem section {
22 | text-align: right;
23 | }
24 |
25 | .ZDAVitrineFlowsItem img {
26 | --OLSKCommonCardImageSize: 210px;
27 |
28 | order: 1;
29 | }
30 |
31 | @media screen and (max-width: 760px) {
32 |
33 | .ZDAVitrineFlowsItem {
34 | flex-direction: column;
35 | }
36 |
37 | .ZDAVitrineFlowsItem section {
38 | text-align: center;
39 | }
40 |
41 | .ZDAVitrineFlowsItem img {
42 | --OLSKCommonCardImageSize: 300px;
43 | }
44 |
45 | }
46 |
47 | .ZDAVitrineProtocolsLink {
48 | display: flex;
49 |
50 | text-decoration: none;
51 |
52 | align-items: center;
53 | }
54 |
55 | .ZDAVitrineProtocolsLinkImage {
56 | --ZDAVitrineProtocolsLinkImageSize: 32px;
57 |
58 | padding: 8px;
59 | width: var(--ZDAVitrineProtocolsLinkImageSize);
60 | max-height: var(--ZDAVitrineProtocolsLinkImageSize);
61 | }
62 |
63 | .ZDAVitrineProtocolsLinkText {
64 | font-size: 120%;
65 | font-family: var(--OLSKCommonHeadingFontFamily);
66 | }
67 |
68 | .ZDAVitrineEventsList td {
69 | border: none !important;
70 | padding: 8px !important;
71 | }
72 |
73 | .ZDAVitrineEventsListItemStart {
74 | font-weight: bold;
75 | font-size: 120%;
76 | font-family: var(--OLSKCommonHeadingFontFamily);
77 | white-space: nowrap;
78 | text-align: center;
79 | }
80 |
81 | .OLSKDecorGlossary {
82 | margin: unset;
83 | background: #e3e0d4;
84 | }
85 |
86 | .OLSKDecorGlossary dd {
87 | margin: 4px 0 10px 0;
88 | }
89 |
90 | .ZDAVitrineGroupDiscussionVideo {
91 | width: 100%;
92 | height: 240px;
93 | border: 0;
94 |
95 | background: black;
96 | }
97 |
98 | .ZDAVitrineEasyIndieCrownName {
99 | text-decoration: none;
100 | }
101 |
--------------------------------------------------------------------------------
/os-app/open-vitrine/ui-test-_access.js:
--------------------------------------------------------------------------------
1 | const kDefaultRoutePath = require('./controller.js').OLSKControllerRoutes().shift().OLSKRoutePath;
2 |
3 | Object.entries({
4 | ZDAVitrine: '.ZDAVitrine',
5 |
6 | ZDAVitrinePrinciplesHeading: '.ZDAVitrinePrinciplesHeading',
7 | ZDAVitrinePrinciplesList: '.ZDAVitrinePrinciplesList',
8 |
9 | ZDAVitrineFlowsHeading: '.ZDAVitrineFlowsHeading',
10 | ZDAVitrineFlowsTraditionalHeading: '.ZDAVitrineFlowsTraditionalHeading',
11 | ZDAVitrineFlowsTraditionalBlurb: '.ZDAVitrineFlowsTraditionalBlurb',
12 | ZDAVitrineFlowsTraditionalImage: '.ZDAVitrineFlowsTraditionalImage',
13 | ZDAVitrineFlowsModernHeading: '.ZDAVitrineFlowsModernHeading',
14 | ZDAVitrineFlowsModernBlurb: '.ZDAVitrineFlowsModernBlurb',
15 | ZDAVitrineFlowsModernImage: '.ZDAVitrineFlowsModernImage',
16 |
17 | ZDAVitrineProtocolsHeading: '.ZDAVitrineProtocolsHeading',
18 | ZDAVitrineProtocolsLink: '.ZDAVitrineProtocolsLink',
19 | ZDAVitrineProtocolsLinkImage: '.ZDAVitrineProtocolsLinkImage',
20 | ZDAVitrineProtocolsLinkText: '.ZDAVitrineProtocolsLinkText',
21 |
22 | ZDAVitrineToolsHeading: '.ZDAVitrineToolsHeading',
23 | ZDAVitrineToolsContainer: '.ZDAVitrineToolsContainer',
24 | ZDAVitrineToolsLink: '.ZDAVitrineToolsLink',
25 | ZDAVitrineToolsBlurb: '.ZDAVitrineToolsBlurb',
26 |
27 | ZDAVitrineEventsHeading: '.ZDAVitrineEventsHeading',
28 |
29 | ZDAVitrineGroupDiscussionHeading: '.ZDAVitrineGroupDiscussionHeading',
30 | ZDAVitrineGroupDiscussionVideo: '.ZDAVitrineGroupDiscussionVideo',
31 |
32 | ZDAVitrineReadingHeading: '.ZDAVitrineReadingHeading',
33 | ZDAVitrineReadingContainer: '.ZDAVitrineReadingContainer',
34 | ZDAVitrineReadingLink: '.ZDAVitrineReadingLink',
35 | ZDAVitrineReadingBlurb: '.ZDAVitrineReadingBlurb',
36 |
37 | ZDAVitrineAdjacentHeading: '.ZDAVitrineAdjacentHeading',
38 | ZDAVitrineAdjacentContainer: '.ZDAVitrineAdjacentContainer',
39 | ZDAVitrineAdjacentLink: '.ZDAVitrineAdjacentLink',
40 | ZDAVitrineAdjacentBlurb: '.ZDAVitrineAdjacentBlurb',
41 |
42 | ZDAVitrineAlsoHeading: '.ZDAVitrineAlsoHeading',
43 | ZDAVitrineEasyIndieCrown: '.ZDAVitrineEasyIndieCrown',
44 | ZDAVitrineEasyIndieCrownIcon: '.ZDAVitrineEasyIndieCrownIcon',
45 | ZDAVitrineEasyIndieCrownName: '.ZDAVitrineEasyIndieCrownName',
46 | ZDAVitrineEasyIndieCrownBlurb: '.ZDAVitrineEasyIndieCrownBlurb',
47 | }).map(function (e) {
48 | return global[e.shift()] = e.pop();
49 | });
50 |
51 | describe('ZDAVitrine_Access', function () {
52 |
53 | const protocols = require('../task-a-banks/controller.js').DataBankProtocols().length;
54 | const tools = require('../task-a-banks/controller.js').DataBankTools().length;
55 | const reading = require('../task-a-banks/controller.js').DataBankReading().length;
56 | const adjacent = require('../task-a-banks/controller.js').DataBankAdjacent().length;
57 |
58 | before(function() {
59 | return browser.visit(kDefaultRoutePath);
60 | });
61 |
62 | it('shows ZDAVitrine', function() {
63 | return browser.assert.elements(ZDAVitrine, 1);
64 | });
65 |
66 | it('shows OLSKCrown', function() {
67 | return browser.assert.elements('.OLSKCrown', 1);
68 | });
69 |
70 | it('shows OLSKLanding', function() {
71 | return browser.assert.elements('.OLSKLanding', 1);
72 | });
73 |
74 | it('shows ZDAVitrinePrinciplesHeading', function () {
75 | return browser.assert.elements(ZDAVitrinePrinciplesHeading, 1);
76 | });
77 |
78 | it('shows ZDAVitrinePrinciplesList', function () {
79 | return browser.assert.elements(ZDAVitrinePrinciplesList, 1);
80 | });
81 |
82 | it('shows ZDAVitrineFlowsHeading', function () {
83 | return browser.assert.elements(ZDAVitrineFlowsHeading, 1);
84 | });
85 |
86 | it('shows ZDAVitrineFlowsTraditionalHeading', function () {
87 | return browser.assert.elements(ZDAVitrineFlowsTraditionalHeading, 1);
88 | });
89 |
90 | it('shows ZDAVitrineFlowsTraditionalBlurb', function () {
91 | return browser.assert.elements(ZDAVitrineFlowsTraditionalBlurb, 1);
92 | });
93 |
94 | it('shows ZDAVitrineFlowsTraditionalImage', function () {
95 | return browser.assert.elements(ZDAVitrineFlowsTraditionalImage, 1);
96 | });
97 |
98 | it('shows ZDAVitrineFlowsModernHeading', function () {
99 | return browser.assert.elements(ZDAVitrineFlowsModernHeading, 1);
100 | });
101 |
102 | it('shows ZDAVitrineFlowsModernBlurb', function () {
103 | return browser.assert.elements(ZDAVitrineFlowsModernBlurb, 1);
104 | });
105 |
106 | it('shows ZDAVitrineFlowsModernImage', function () {
107 | return browser.assert.elements(ZDAVitrineFlowsModernImage, 1);
108 | });
109 |
110 | it('shows ZDAVitrineProtocolsHeading', function () {
111 | return browser.assert.elements(ZDAVitrineProtocolsHeading, 1);
112 | });
113 |
114 | it.skip('shows ZDAVitrineProtocolsLink', function () {
115 | return browser.assert.elements(ZDAVitrineProtocolsLink, protocols);
116 | });
117 |
118 | it.skip('shows ZDAVitrineProtocolsLinkImage', function () {
119 | return browser.assert.elements(ZDAVitrineProtocolsLinkImage, protocols);
120 | });
121 |
122 | it.skip('shows ZDAVitrineProtocolsLinkText', function () {
123 | return browser.assert.elements(ZDAVitrineProtocolsLinkText, protocols);
124 | });
125 |
126 | it('shows ZDAVitrineToolsHeading', function () {
127 | return browser.assert.elements(ZDAVitrineToolsHeading, 1);
128 | });
129 |
130 | it('shows ZDAVitrineToolsContainer', function () {
131 | return browser.assert.elements(ZDAVitrineToolsContainer, 1);
132 | });
133 |
134 | it.skip('shows ZDAVitrineToolsLink', function () {
135 | return browser.assert.elements(ZDAVitrineToolsLink, tools);
136 | });
137 |
138 | it.skip('shows ZDAVitrineToolsBlurb', function () {
139 | return browser.assert.elements(ZDAVitrineToolsBlurb, tools);
140 | });
141 |
142 | it('shows ZDAVitrineEventsHeading', function () {
143 | return browser.assert.elements(ZDAVitrineEventsHeading, 1);
144 | });
145 |
146 | it('shows ZDAVitrineEventsList', function () {
147 | return browser.assert.elements('.ZDAVitrineEventsList', 1);
148 | });
149 |
150 | it('shows ZDAVitrineGroupDiscussionHeading', function () {
151 | return browser.assert.elements(ZDAVitrineGroupDiscussionHeading, 1);
152 | });
153 |
154 | it('shows ZDAVitrineGroupDiscussionVideo', function () {
155 | return browser.assert.elements(ZDAVitrineGroupDiscussionVideo, 1);
156 | });
157 |
158 | it('shows ZDAVitrineReadingHeading', function () {
159 | return browser.assert.elements(ZDAVitrineReadingHeading, 1);
160 | });
161 |
162 | it('shows ZDAVitrineReadingContainer', function () {
163 | return browser.assert.elements(ZDAVitrineReadingContainer, 1);
164 | });
165 |
166 | it.skip('shows ZDAVitrineReadingLink', function () {
167 | return browser.assert.elements(ZDAVitrineReadingLink, reading);
168 | });
169 |
170 | it.skip('shows ZDAVitrineReadingBlurb', function () {
171 | return browser.assert.elements(ZDAVitrineReadingBlurb, reading);
172 | });
173 |
174 | it('shows ZDAVitrineAdjacentHeading', function () {
175 | return browser.assert.elements(ZDAVitrineAdjacentHeading, 1);
176 | });
177 |
178 | it('shows ZDAVitrineAdjacentContainer', function () {
179 | return browser.assert.elements(ZDAVitrineAdjacentContainer, 1);
180 | });
181 |
182 | it.skip('shows ZDAVitrineAdjacentLink', function () {
183 | return browser.assert.elements(ZDAVitrineAdjacentLink, adjacent);
184 | });
185 |
186 | it.skip('shows ZDAVitrineAdjacentBlurb', function () {
187 | return browser.assert.elements(ZDAVitrineAdjacentBlurb, adjacent);
188 | });
189 |
190 | it('shows ROCOGazette', function () {
191 | return browser.assert.elements('.ROCOGazette', 1);
192 | });
193 |
194 | it('shows OLSKEdit', function () {
195 | return browser.assert.elements('.OLSKEdit', 1);
196 | });
197 |
198 | it('shows ZDAVitrineAlsoHeading', function () {
199 | return browser.assert.elements(ZDAVitrineAlsoHeading, 1);
200 | });
201 |
202 | it('shows ZDAVitrineEasyIndieCrown', function () {
203 | return browser.assert.elements(ZDAVitrineEasyIndieCrown, 1);
204 | });
205 |
206 | it('shows ZDAVitrineEasyIndieCrownIcon', function () {
207 | return browser.assert.elements(ZDAVitrineEasyIndieCrownIcon, 1);
208 | });
209 |
210 | it('shows ZDAVitrineEasyIndieCrownName', function () {
211 | return browser.assert.elements(ZDAVitrineEasyIndieCrownName, 1);
212 | });
213 |
214 | it('shows ZDAVitrineEasyIndieCrownBlurb', function () {
215 | return browser.assert.elements(ZDAVitrineEasyIndieCrownBlurb, 1);
216 | });
217 |
218 | it('shows SWARLink', function() {
219 | return browser.assert.elements('.SWARLink', 1);
220 | });
221 |
222 | it('shows ROCORootLink', function() {
223 | return browser.assert.elements('.ROCORootLink', 1);
224 | });
225 |
226 | });
227 |
--------------------------------------------------------------------------------
/os-app/open-vitrine/ui-test-_localize.js:
--------------------------------------------------------------------------------
1 | const kDefaultRoute = require('./controller.js').OLSKControllerRoutes().shift();
2 |
3 | kDefaultRoute.OLSKRouteLanguageCodes.forEach(function (OLSKRoutingLanguage) {
4 |
5 | const uLocalized = function (inputData) {
6 | return OLSKTestingLocalized(inputData, OLSKRoutingLanguage);
7 | };
8 |
9 | describe('ZDAVitrine_Localize-' + OLSKRoutingLanguage, function () {
10 |
11 | before(function() {
12 | return browser.OLSKVisit(kDefaultRoute, {
13 | OLSKRoutingLanguage,
14 | });
15 | });
16 |
17 | it('localizes title', function() {
18 | return browser.assert.text('title', uLocalized('ZDAVitrineTitle'));
19 | });
20 |
21 | it('localizes meta[description]', function() {
22 | return browser.assert.attribute('meta[name=description]', 'content', uLocalized('ZDAVitrineDescription'));
23 | });
24 |
25 | it('localizes ZDAVitrinePrinciplesHeading', function () {
26 | return browser.assert.text(ZDAVitrinePrinciplesHeading, uLocalized('ZDAVitrinePrinciplesHeadingText'));
27 | });
28 |
29 | uLocalized('ZDAVitrinePrinciplesListItemText').forEach(function (e, i) {
30 | it('localizes ZDAVitrinePrinciplesListItem', function () {
31 | return browser.assert.OLSKInnerHTML(`.ZDAVitrinePrinciplesListItem:nth-child(${ i + 1 })`, e);
32 | });
33 | });
34 |
35 | it('localizes ZDAVitrineFlowsHeading', function () {
36 | return browser.assert.text(ZDAVitrineFlowsHeading, uLocalized('ZDAVitrineFlowsHeadingText'));
37 | });
38 |
39 | it('localizes ZDAVitrineFlowsTraditionalHeading', function () {
40 | return browser.assert.OLSKInnerHTML(ZDAVitrineFlowsTraditionalHeading, uLocalized('ZDAVitrineFlowsTraditionalHeadingText'));
41 | });
42 |
43 | it('localizes ZDAVitrineFlowsTraditionalBlurb', function () {
44 | return browser.assert.OLSKInnerHTML(ZDAVitrineFlowsTraditionalBlurb, uLocalized('ZDAVitrineFlowsTraditionalBlurbText'));
45 | });
46 |
47 | it('localizes ZDAVitrineFlowsModernHeading', function () {
48 | return browser.assert.OLSKInnerHTML(ZDAVitrineFlowsModernHeading, uLocalized('ZDAVitrineFlowsModernHeadingText'));
49 | });
50 |
51 | it('localizes ZDAVitrineFlowsModernBlurb', function () {
52 | return browser.assert.OLSKInnerHTML(ZDAVitrineFlowsModernBlurb, uLocalized('ZDAVitrineFlowsModernBlurbText'));
53 | });
54 |
55 | it('localizes ZDAVitrineProtocolsHeading', function () {
56 | return browser.assert.text(ZDAVitrineProtocolsHeading, uLocalized('ZDAVitrineProtocolsHeadingText'));
57 | });
58 |
59 | it('localizes ZDAVitrineToolsHeading', function () {
60 | return browser.assert.text(ZDAVitrineToolsHeading, uLocalized('ZDAVitrineToolsHeadingText'));
61 | });
62 |
63 | it('localizes ZDAVitrineEventsHeading', function () {
64 | return browser.assert.text(ZDAVitrineEventsHeading, uLocalized('ZDAVitrineEventsHeadingText'));
65 | });
66 |
67 | it('localizes ZDAVitrineGroupDiscussionHeading', function () {
68 | return browser.assert.text(ZDAVitrineGroupDiscussionHeading, uLocalized('ZDAVitrineGroupDiscussionHeadingText'));
69 | });
70 |
71 | it('localizes ZDAVitrineReadingHeading', function () {
72 | return browser.assert.text(ZDAVitrineReadingHeading, uLocalized('ZDAVitrineReadingHeadingText'));
73 | });
74 |
75 | it('localizes ZDAVitrineAdjacentHeading', function () {
76 | return browser.assert.text(ZDAVitrineAdjacentHeading, uLocalized('ZDAVitrineAdjacentHeadingText'));
77 | });
78 |
79 | it('localizes ZDAVitrineAlsoHeading', function () {
80 | return browser.assert.text(ZDAVitrineAlsoHeading, uLocalized('ZDAVitrineAlsoHeadingText'));
81 | });
82 |
83 | it('localizes ZDAVitrineEasyIndieCrownBlurb', function () {
84 | return browser.assert.text(ZDAVitrineEasyIndieCrownBlurb, uLocalized('ZDAVitrineEasyIndieCrownBlurbText'));
85 | });
86 |
87 | context('OLSKCrown', function test_OLSKCrown () {
88 |
89 | it('localizes OLSKCrownCardName', function () {
90 | return browser.assert.text('.OLSKCrownCardName', uLocalized('ZDAVitrineTitle'));
91 | });
92 |
93 | });
94 |
95 | context('OLSKLanding', function test_OLSKLanding () {
96 |
97 | it('localizes OLSKLandingHeadingText', function () {
98 | return browser.assert.text('.OLSKLandingHeading', uLocalized('ZDAVitrineDescription'));
99 | });
100 |
101 | it('localizes OLSKLandingBlurbText', function () {
102 | return browser.assert.text('.OLSKLandingBlurb', uLocalized('OLSKLandingBlurbText'));
103 | });
104 |
105 | it.skip('localizes OLSKLandingActionText', function () {
106 | return browser.assert.text('.OLSKLandingAction', OLSKTestingFormatted(uLocalized('OLSKLandingActionTextFormat'), require('../open-glance/controller.js').OLSKControllerSharedLocals().ZDAGlanceProjectsCount()));
107 | });
108 |
109 | });
110 |
111 | });
112 |
113 | });
114 |
--------------------------------------------------------------------------------
/os-app/open-vitrine/ui-test-_misc.js:
--------------------------------------------------------------------------------
1 | const kDefaultRoute = require('./controller.js').OLSKControllerRoutes().shift();
2 |
3 | describe('ZDAVitrine_Misc', function () {
4 |
5 | const protocols = require('../task-a-banks/controller.js').DataBankProtocols();
6 | const tools = require('../task-a-banks/controller.js').DataBankTools();
7 | const reading = require('../task-a-banks/controller.js').DataBankReading();
8 | const adjacent = require('../task-a-banks/controller.js').DataBankAdjacent();
9 |
10 | before(function () {
11 | return browser.visit(kDefaultRoute.OLSKRoutePath);
12 | });
13 |
14 | describe('ZDAVitrine', function () {
15 |
16 | it('classes OLSKDecor', function () {
17 | return browser.assert.hasClass(ZDAVitrine, 'OLSKDecor');
18 | });
19 |
20 | it('classes OLSKDecorCapped', function () {
21 | return browser.assert.hasClass(ZDAVitrine, 'OLSKDecorCapped');
22 | });
23 |
24 | it('classes OLSKDecorNoTopPad', function () {
25 | return browser.assert.hasClass(ZDAVitrine, 'OLSKDecorNoTopPad');
26 | });
27 |
28 | });
29 |
30 | describe('OLSKCrown', function test_OLSKCrown () {
31 |
32 | it('sets OLSKCrownCardImageURL', function () {
33 | return browser.assert.attribute('.OLSKCrownCardImage', 'src', process.env.ZDA_VITRINE_IDENTITY_URL);
34 | });
35 |
36 | });
37 |
38 | describe('OLSKLanding', function test_OLSKLanding () {
39 |
40 | it('sets OLSKLandingActionHref', function () {
41 | return browser.assert.attribute('.OLSKLandingAction', 'href', OLSKTestingCanonical(require('../open-glance/controller.js').OLSKControllerRoutes().shift()));
42 | });
43 |
44 | });
45 |
46 | describe('ZDAVitrineFlowsTraditionalImage', function test_ZDAVitrineFlowsTraditionalImage() {
47 |
48 | it('sets role', function () {
49 | return browser.assert.attribute(ZDAVitrineFlowsTraditionalImage, 'role', 'presentation');
50 | });
51 |
52 | it('sets src', function () {
53 | return browser.assert.attribute(ZDAVitrineFlowsTraditionalImage, 'src', process.env.ZDA_VITRINE_FLOWS_TRADITIONAL_URL);
54 | });
55 |
56 | });
57 |
58 | describe('ZDAVitrineFlowsModernImage', function test_ZDAVitrineFlowsModernImage() {
59 |
60 | it('sets role', function () {
61 | return browser.assert.attribute(ZDAVitrineFlowsModernImage, 'role', 'presentation');
62 | });
63 |
64 | it('sets src', function () {
65 | return browser.assert.attribute(ZDAVitrineFlowsModernImage, 'src', process.env.ZDA_VITRINE_FLOWS_MODERN_URL);
66 | });
67 |
68 | });
69 |
70 | protocols.forEach(function (e, i) {
71 |
72 | describe('ZDAVitrineProtocolsLink', function test_ZDAVitrineProtocolsLink() {
73 |
74 | it('sets href', function () {
75 | return browser.assert.attribute(`${ ZDAVitrineProtocolsLink }:nth-of-type(${ i + 1 })`, 'href', e.ZDAProtocolURL);
76 | });
77 |
78 | it('sets target', function () {
79 | return browser.assert.attribute(`${ ZDAVitrineProtocolsLink }:nth-of-type(${ i + 1 })`, 'target', '_blank');
80 | });
81 |
82 | });
83 |
84 | describe('ZDAVitrineProtocolsLinkImage', function test_ZDAVitrineProtocolsLinkImage() {
85 |
86 | it('sets src', function () {
87 | return browser.assert.attribute(`${ ZDAVitrineProtocolsLink }:nth-of-type(${ i + 1 }) ${ ZDAVitrineProtocolsLinkImage }`, 'src', e._ZDAProtocolIconURLCachedPath || e.ZDAProtocolIconURL);
88 | });
89 |
90 | });
91 |
92 | describe('ZDAVitrineProtocolsLinkText', function test_ZDAVitrineProtocolsLinkText() {
93 |
94 | it('sets text', function () {
95 | return browser.assert.text(`${ ZDAVitrineProtocolsLink }:nth-of-type(${ i + 1 }) ${ ZDAVitrineProtocolsLinkText }`, e.ZDAProtocolName);
96 | });
97 |
98 | });
99 |
100 | });
101 |
102 | describe('ZDAVitrineToolsContainer', function test_ZDAVitrineToolsContainer() {
103 |
104 | it('classes OLSKDecorGlossary', function () {
105 | return browser.assert.hasClass(ZDAVitrineToolsContainer, 'OLSKDecorGlossary');
106 | });
107 |
108 | it('sets lang', function () {
109 | return browser.assert.attribute(ZDAVitrineToolsContainer, 'lang', 'en');
110 | });
111 |
112 | });
113 |
114 | tools.forEach(function (e, i) {
115 |
116 | context(e.ZDAToolURL, function () {
117 |
118 | describe('ZDAVitrineToolsLink', function test_ZDAVitrineToolsLink() {
119 |
120 | it('sets href', function () {
121 | return browser.assert.attribute(`dt:nth-of-type(${ i + 1 }) ${ ZDAVitrineToolsLink }`, 'href', e.ZDAToolURL);
122 | });
123 |
124 | it('sets target', function () {
125 | return browser.assert.attribute(`dt:nth-of-type(${ i + 1 }) ${ ZDAVitrineToolsLink }`, 'target', '_blank');
126 | });
127 |
128 | it('sets text', function () {
129 | return browser.assert.text(`dt:nth-of-type(${ i + 1 }) ${ ZDAVitrineToolsLink }`, e.ZDAToolName);
130 | });
131 |
132 | });
133 |
134 | describe('ZDAVitrineToolsBlurb', function test_ZDAVitrineToolsBlurb() {
135 |
136 | it('sets text', function () {
137 | return browser.assert.text(`${ ZDAVitrineToolsBlurb }:nth-of-type(${ i + 1 })`, e.ZDAToolBlurb);
138 | });
139 |
140 | });
141 |
142 | });
143 |
144 | });
145 |
146 | describe('ZDAVitrineGroupDiscussionVideo', function test_ZDAVitrineGroupDiscussionVideo () {
147 |
148 | it('sets src', function () {
149 | return browser.assert.attribute(ZDAVitrineGroupDiscussionVideo, 'src', process.env.ZDA_VITRINE_GROUP_DISCUSSION_VIDEO_URL);
150 | });
151 |
152 | it('sets allowfullscreen', function () {
153 | return browser.assert.attribute(ZDAVitrineGroupDiscussionVideo, 'allowfullscreen', '');
154 | });
155 |
156 | });
157 |
158 | describe('ZDAVitrineReadingContainer', function test_ZDAVitrineReadingContainer() {
159 |
160 | it('classes OLSKDecorGlossary', function () {
161 | return browser.assert.hasClass(ZDAVitrineReadingContainer, 'OLSKDecorGlossary');
162 | });
163 |
164 | it('sets lang', function () {
165 | return browser.assert.attribute(ZDAVitrineReadingContainer, 'lang', 'en');
166 | });
167 |
168 | });
169 |
170 | reading.forEach(function (e, i) {
171 |
172 | context(e.ZDAReadingURL, function () {
173 |
174 | describe('ZDAVitrineReadingLink', function test_ZDAVitrineReadingLink() {
175 |
176 | it('sets href', function () {
177 | return browser.assert.attribute(`dt:nth-of-type(${ i + 1 }) ${ ZDAVitrineReadingLink }`, 'href', e.ZDAReadingURL);
178 | });
179 |
180 | it('sets target', function () {
181 | return browser.assert.attribute(`dt:nth-of-type(${ i + 1 }) ${ ZDAVitrineReadingLink }`, 'target', '_blank');
182 | });
183 |
184 | it('sets text', function () {
185 | return browser.assert.text(`dt:nth-of-type(${ i + 1 }) ${ ZDAVitrineReadingLink }`, e.ZDAReadingName);
186 | });
187 |
188 | });
189 |
190 | describe('ZDAVitrineReadingBlurb', function test_ZDAVitrineReadingBlurb() {
191 |
192 | it('sets text', function () {
193 | return browser.assert.text(`${ ZDAVitrineReadingBlurb }:nth-of-type(${ i + 1 })`, e.ZDAReadingBlurb);
194 | });
195 |
196 | });
197 |
198 | });
199 |
200 | });
201 |
202 | describe('ZDAVitrineAdjacentContainer', function test_ZDAVitrineAdjacentContainer() {
203 |
204 | it('classes OLSKDecorGlossary', function () {
205 | return browser.assert.hasClass(ZDAVitrineAdjacentContainer, 'OLSKDecorGlossary');
206 | });
207 |
208 | it('sets lang', function () {
209 | return browser.assert.attribute(ZDAVitrineAdjacentContainer, 'lang', 'en');
210 | });
211 |
212 | });
213 |
214 | adjacent.forEach(function (e, i) {
215 |
216 | context(e.ZDAAdjacentURL, function () {
217 |
218 | describe('ZDAVitrineAdjacentLink', function test_ZDAVitrineAdjacentLink() {
219 |
220 | it('sets href', function () {
221 | return browser.assert.attribute(`dt:nth-of-type(${ i + 1 }) ${ ZDAVitrineAdjacentLink }`, 'href', e.ZDAAdjacentURL);
222 | });
223 |
224 | it('sets target', function () {
225 | return browser.assert.attribute(`dt:nth-of-type(${ i + 1 }) ${ ZDAVitrineAdjacentLink }`, 'target', '_blank');
226 | });
227 |
228 | it('sets text', function () {
229 | return browser.assert.text(`dt:nth-of-type(${ i + 1 }) ${ ZDAVitrineAdjacentLink }`, e.ZDAAdjacentName);
230 | });
231 |
232 | });
233 |
234 | describe('ZDAVitrineAdjacentBlurb', function test_ZDAVitrineAdjacentBlurb() {
235 |
236 | it('sets text', function () {
237 | return browser.assert.text(`${ ZDAVitrineAdjacentBlurb }:nth-of-type(${ i + 1 })`, e.ZDAAdjacentBlurb);
238 | });
239 |
240 | });
241 |
242 | });
243 |
244 | });
245 |
246 | describe('ROCOGazette', function test_ROCOGazette () {
247 |
248 | it.skip('sets ROCOBulletinProject', function () {
249 | return browser.assert.attribute('.ROCOBulletinProjectField', 'value', 'Zero Data App');
250 | });
251 |
252 | });
253 |
254 | describe('OLSKEdit', function test_OLSKEdit () {
255 |
256 | it('sets OLSKEditURL', function () {
257 | return browser.assert.attribute('.OLSKEdit', 'href', process.env.OLSK_REPO_URL);
258 | });
259 |
260 | });
261 |
262 | describe('ZDAVitrineEasyIndieCrown', function test_ZDAVitrineEasyIndieCrown() {
263 |
264 | it('classes OLSKCommonCard', function () {
265 | return browser.assert.hasClass(ZDAVitrineEasyIndieCrown, 'OLSKCommonCard');
266 | });
267 |
268 | it('classes OLSKCommonCrownCard', function () {
269 | return browser.assert.hasClass(ZDAVitrineEasyIndieCrown, 'OLSKCommonCrownCard');
270 | });
271 |
272 | });
273 |
274 | describe('ZDAVitrineEasyIndieCrownIcon', function () {
275 |
276 | it('sets role', function () {
277 | return browser.assert.attribute(ZDAVitrineEasyIndieCrownIcon, 'role', 'presentation');
278 | });
279 |
280 | it('sets src', function () {
281 | return browser.assert.attribute(ZDAVitrineEasyIndieCrownIcon, 'src', process.env.ZDA_VITRINE_EASY_INDIE_IDENTITY_URL);
282 | });
283 |
284 | });
285 |
286 | describe('ZDAVitrineEasyIndieCrownName', function test_ZDAVitrineEasyIndieCrownName () {
287 |
288 | it('sets href', function () {
289 | return browser.assert.attribute(ZDAVitrineEasyIndieCrownName, 'href', process.env.ZDA_VITRINE_EASY_INDIE_URL);
290 | });
291 |
292 | it('sets text', function () {
293 | return browser.assert.text(ZDAVitrineEasyIndieCrownName, 'Easy Indie App');
294 | });
295 |
296 | });
297 |
298 | });
299 |
--------------------------------------------------------------------------------
/os-app/open-vitrine/ui-view.ejs:
--------------------------------------------------------------------------------
1 | <%
2 | locals.OLSKPageTitle = OLSKLocalized('ZDAVitrineTitle');
3 | locals.OLSKPageCanonical = 'https://0data.app';
4 | locals.OLSKPageDescription = OLSKLocalized('ZDAVitrineDescription');
5 | locals.OLSKPageAssets = [
6 | '/_shared/__external/normalize.css/normalize.css',
7 | '/_shared/__external/OLSKDecor/ui-style.css',
8 | '/_shared/common/ui-style.css',
9 | 'ui-style.css',
10 | ];
11 | %>
12 |
13 |
14 |
15 | <%- include('../../node_modules/OLSKCrown/main.ejs', {
16 | OLSKCrownCardImageURL: process.env.ZDA_VITRINE_IDENTITY_URL,
17 | OLSKCrownCardNameText: OLSKLocalized('ZDAVitrineTitle'),
18 | }) %>
19 |
20 | <%- include('../../node_modules/OLSKLanding/main.ejs', {
21 | OLSKLandingHeadingText: OLSKLocalized('ZDAVitrineDescription').replace(', all of it', ',
all of it'),
22 | OLSKLandingBlurbText: OLSKLocalized('OLSKLandingBlurbText'),
23 | OLSKLandingActionText: OLSKFormatted(OLSKLocalized('OLSKLandingActionTextFormat'), ZDAGlanceProjectsCount()),
24 | OLSKLandingActionHref: OLSKCanonical('ZDAGlanceRoute'),
25 | }) %>
26 |
27 |
<%= OLSKLocalized('ZDAVitrinePrinciplesHeadingText') %>
28 |
29 |
30 | <% OLSKLocalized('ZDAVitrinePrinciplesListItemText').forEach(function (e) { -%>
31 | - <%- e %>
32 | <% }) -%>
33 |
34 |
35 |
<%= OLSKLocalized('ZDAVitrineFlowsHeadingText') %>
36 |
37 |
38 |

39 |
40 | <%- OLSKLocalized('ZDAVitrineFlowsTraditionalHeadingText') %>
41 | <%- OLSKLocalized('ZDAVitrineFlowsTraditionalBlurbText') %>
42 |
43 |
44 |
45 |
46 |

47 |
48 | <%- OLSKLocalized('ZDAVitrineFlowsModernHeadingText') %>
49 | <%- OLSKLocalized('ZDAVitrineFlowsModernBlurbText') %>
50 |
51 |
52 |
53 |
<%= OLSKLocalized('ZDAVitrineProtocolsHeadingText') %>
54 |
55 | <% ZDAProtocols().forEach(function (item) { -%>
56 |
57 |
58 | <%= item.ZDAProtocolName %>
59 |
60 | <% }) -%>
61 |
62 |
63 |
64 | <% ZDATools().forEach(function (item) { -%>
65 | - <%= item.ZDAToolName %>
66 | - <%= item.ZDAToolBlurb %>
67 | <% }) -%>
68 |
69 |
70 |
<%= OLSKLocalized('ZDAVitrineEventsHeadingText') %>
71 |
72 | <%- include('../sub-events/ui-view.ejs', {
73 | ZDAVitrineEventsListData: ZDAEvents(),
74 | }) %>
75 |
76 |
77 |
78 |
85 |
86 |
<%= OLSKLocalized('ZDAVitrineGroupDiscussionHeadingText') %>
87 |
88 |
89 |
<%= OLSKLocalized('ZDAVitrineReadingHeadingText') %> 💊
90 |
91 | <% ZDAReading().forEach(function (item) { -%>
92 | - <%= item.ZDAReadingName %>
93 | - <%= item.ZDAReadingBlurb %>
94 | <% }) -%>
95 |
96 |
97 |
<%= OLSKLocalized('ZDAVitrineAdjacentHeadingText') %>
98 |
99 | <% ZDAAdjacent().forEach(function (item) { -%>
100 | - <%= item.ZDAAdjacentName %>
101 | - <%= item.ZDAAdjacentBlurb %>
102 | <% }) -%>
103 |
104 |
105 | <%- include('../../node_modules/ROCOGazette/main.ejs', {
106 | _OLSKModulesDirPrefix: '../.',
107 | ROCOBulletinProject: 'Zero Data App',
108 | }) %>
109 |
110 | <%- include('../../node_modules/OLSKEdit/main.ejs', {
111 | OLSKEditURL: process.env.OLSK_REPO_URL,
112 | }) %>
113 |
114 |
<%= OLSKLocalized('ZDAVitrineAlsoHeadingText') %>
115 |
116 |

117 |
121 |
122 |
123 |
124 |
125 | <%- include('../../node_modules/SWARLink/main.ejs') %>
126 |
127 | <%- include('../_shared/__external/ROCORootLink/main.ejs') %>
128 |
129 |
130 |
--------------------------------------------------------------------------------
/os-app/sub-events/controller.js:
--------------------------------------------------------------------------------
1 | const mod = {
2 |
3 | OLSKControllerSharedLocals () {
4 | return {
5 | ZDAVitrineEventsListDateFormat (inputData) {
6 | return require('luxon').DateTime.fromJSDate(inputData).toFormat('MMM dd');
7 | },
8 | };
9 | },
10 |
11 | OLSKControllerRoutes () {
12 | return [{
13 | OLSKRoutePath: '/stub/ZDAVitrineEventsList',
14 | OLSKRouteMethod: 'get',
15 | OLSKRouteFunction: (function ZDAVitrineEventsListStubRoute (req, res, next) {
16 | return res.OLSKExpressLayoutRender(require('path').join(__dirname, 'ui-view'), Object.assign({
17 | ZDAVitrineEventsListData: [],
18 | }, Object.fromEntries(Array.from((new URLSearchParams(req.query)).entries()).map(function (e) {
19 | if (e[0] === 'ZDAVitrineEventsListData') {
20 | (e[1] = JSON.parse(e[1])).forEach(function (e) {
21 | e.ZDAEventStart = new Date(e.ZDAEventStart);
22 | });
23 | }
24 |
25 | return e;
26 | }))));
27 | }),
28 | OLSKRouteSignature: 'ZDAVitrineEventsListStubRoute',
29 | OLSKRouteLanguageCodes: ['en', 'fr', 'es', 'pt'],
30 | OLSKRouteIsHidden: process.env.NODE_ENV === 'production',
31 | }];
32 | },
33 |
34 | };
35 |
36 | Object.assign(exports, mod);
37 |
--------------------------------------------------------------------------------
/os-app/sub-events/i18n-en.yml:
--------------------------------------------------------------------------------
1 | ZDAVitrineEventsListEmptyText: No events
2 |
--------------------------------------------------------------------------------
/os-app/sub-events/i18n-es.yml:
--------------------------------------------------------------------------------
1 | ZDAVitrineEventsListEmptyText: No hay eventos
2 |
--------------------------------------------------------------------------------
/os-app/sub-events/i18n-fr.yml:
--------------------------------------------------------------------------------
1 | ZDAVitrineEventsListEmptyText: Pas d'événements
2 |
--------------------------------------------------------------------------------
/os-app/sub-events/i18n-pt.yml:
--------------------------------------------------------------------------------
1 | ZDAVitrineEventsListEmptyText: Não tem eventos
2 |
--------------------------------------------------------------------------------
/os-app/sub-events/ui-test-_access.js:
--------------------------------------------------------------------------------
1 | const kDefaultRoute = require('./controller.js').OLSKControllerRoutes().shift();
2 |
3 | Object.entries({
4 | ZDAVitrineEventsList: '.ZDAVitrineEventsList',
5 |
6 | ZDAVitrineEventsListEmpty: '.ZDAVitrineEventsListEmpty',
7 |
8 | ZDAVitrineEventsListItem: '.ZDAVitrineEventsListItem',
9 |
10 | ZDAVitrineEventsListItemStart: '.ZDAVitrineEventsListItemStart',
11 | ZDAVitrineEventsListItemLink: '.ZDAVitrineEventsListItemLink',
12 | }).map(function (e) {
13 | return global[e.shift()] = e.pop();
14 | });
15 |
16 | describe('ZDAVitrineEventsList_Access', function () {
17 |
18 | before(function() {
19 | return browser.OLSKVisit(kDefaultRoute);
20 | });
21 |
22 | it('shows ZDAVitrineEventsList', function() {
23 | return browser.assert.elements(ZDAVitrineEventsList, 1);
24 | });
25 |
26 | it('shows ZDAVitrineEventsListEmpty', function () {
27 | return browser.assert.elements(ZDAVitrineEventsListEmpty, 1);
28 | });
29 |
30 | it('hides ZDAVitrineEventsListItem', function () {
31 | return browser.assert.elements(ZDAVitrineEventsListItem, 0);
32 | });
33 |
34 | context('ZDAVitrineEventsListData', function () {
35 |
36 | const count = Math.max(1, Date.now() % 10);
37 |
38 | before(function() {
39 | return browser.OLSKVisit(kDefaultRoute, {
40 | ZDAVitrineEventsListData: JSON.stringify(Array.from(Array(count)).map(function (e) {
41 | return {
42 | ZDAEventStart: new Date(),
43 | };
44 | })),
45 | });
46 | });
47 |
48 | it('hides ZDAVitrineEventsListEmpty', function () {
49 | return browser.assert.elements(ZDAVitrineEventsListEmpty, 0);
50 | });
51 |
52 | it('shows ZDAVitrineEventsListItem', function () {
53 | return browser.assert.elements(ZDAVitrineEventsListItem, count);
54 | });
55 |
56 | it('shows ZDAVitrineEventsListItemStart', function () {
57 | return browser.assert.elements(ZDAVitrineEventsListItemStart, count);
58 | });
59 |
60 | it('shows ZDAVitrineEventsListItemLink', function () {
61 | return browser.assert.elements(ZDAVitrineEventsListItemLink, count);
62 | });
63 |
64 | });
65 |
66 | });
67 |
--------------------------------------------------------------------------------
/os-app/sub-events/ui-test-_localize.js:
--------------------------------------------------------------------------------
1 | const kDefaultRoute = require('./controller.js').OLSKControllerRoutes().shift();
2 |
3 | kDefaultRoute.OLSKRouteLanguageCodes.forEach(function (OLSKRoutingLanguage) {
4 |
5 | const uLocalized = function (inputData) {
6 | return OLSKTestingLocalized(inputData, OLSKRoutingLanguage);
7 | };
8 |
9 | describe('ZDAVitrineEventsList_Localize-' + OLSKRoutingLanguage, function () {
10 |
11 | before(function() {
12 | return browser.OLSKVisit(kDefaultRoute, {
13 | OLSKRoutingLanguage,
14 | });
15 | });
16 |
17 | it('localizes ZDAVitrineEventsListEmpty', function () {
18 | return browser.assert.text(ZDAVitrineEventsListEmpty, uLocalized('ZDAVitrineEventsListEmptyText'));
19 | });
20 |
21 | });
22 |
23 | });
24 |
--------------------------------------------------------------------------------
/os-app/sub-events/ui-test-_misc.js:
--------------------------------------------------------------------------------
1 | const kDefaultRoute = require('./controller.js').OLSKControllerRoutes().shift();
2 |
3 | const ZDABank = require('../_shared/ZDABank/main.js');
4 |
5 | describe('ZDAVitrineEventsList_Misc', function () {
6 |
7 | const item = {
8 | ZDAEventURL: Math.random().toString(),
9 | ZDAEventName: Math.random().toString(),
10 | ZDAEventStart: new Date(),
11 | };
12 |
13 | before(function() {
14 | return browser.OLSKVisit(kDefaultRoute, {
15 | ZDAVitrineEventsListData: JSON.stringify([item]),
16 | });
17 | });
18 |
19 | describe('ZDAVitrineEventsList', function test_ZDAVitrineEventsList () {
20 |
21 | it('sets lang', function () {
22 | return browser.assert.attribute(ZDAVitrineEventsList, 'lang', 'en');
23 | });
24 |
25 | });
26 |
27 | describe('ZDAVitrineEventsListItemStart', function test_ZDAVitrineEventsListItemStart () {
28 |
29 | it('binds ZDAEventStart', function () {
30 | return browser.assert.text(ZDAVitrineEventsListItemStart, require('luxon').DateTime.fromJSDate(item.ZDAEventStart).toFormat('MMM dd'));
31 | });
32 |
33 | });
34 |
35 | describe('ZDAVitrineEventsListItemLink', function test_ZDAVitrineEventsListItemLink () {
36 |
37 | it('sets href', function () {
38 | return browser.assert.attribute(ZDAVitrineEventsListItemLink, 'href', item.ZDAEventURL);
39 | });
40 |
41 | it('sets target', function () {
42 | return browser.assert.attribute(ZDAVitrineEventsListItemLink, 'target', '_blank');
43 | });
44 |
45 | it('binds ZDAEventName', function () {
46 | return browser.assert.text(ZDAVitrineEventsListItemLink, item.ZDAEventName);
47 | });
48 |
49 | });
50 |
51 | });
52 |
--------------------------------------------------------------------------------
/os-app/sub-events/ui-view.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 | <% if (!ZDAVitrineEventsListData.length) { -%>
4 |
<%= OLSKLocalized('ZDAVitrineEventsListEmptyText') %>
5 | <% } -%>
6 |
7 |
8 | <% ZDAVitrineEventsListData.forEach(function (item) { -%>
9 |
10 | <%= ZDAVitrineEventsListDateFormat(item.ZDAEventStart) %> |
11 | <%= item.ZDAEventName %> |
12 |
13 | <% }) -%>
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/os-app/sub-list/controller.js:
--------------------------------------------------------------------------------
1 | const mod = {
2 |
3 | OLSKControllerRoutes () {
4 | return [{
5 | OLSKRoutePath: '/stub/ZDAGlanceList',
6 | OLSKRouteMethod: 'get',
7 | OLSKRouteFunction: (function ZDAGlanceListStubRoute (req, res, next) {
8 | return res.OLSKExpressLayoutRender(require('path').join(__dirname, 'ui-view'), Object.assign({
9 | ZDAGlanceListData: [],
10 | }, Object.fromEntries(Array.from((new URLSearchParams(req.query)).entries()).map(function (e) {
11 | if (e[0] === 'ZDAGlanceListData') {
12 | e[1] = JSON.parse(e[1]);
13 | }
14 |
15 | return e;
16 | }))));
17 | }),
18 | OLSKRouteSignature: 'ZDAGlanceListStubRoute',
19 | OLSKRouteLanguageCodes: ['en', 'fr', 'es', 'pt'],
20 | OLSKRouteIsHidden: process.env.NODE_ENV === 'production',
21 | }];
22 | },
23 |
24 | };
25 |
26 | Object.assign(exports, mod);
27 |
--------------------------------------------------------------------------------
/os-app/sub-list/i18n-en.yml:
--------------------------------------------------------------------------------
1 | ZDAGlanceListEmptyText: No data
2 |
--------------------------------------------------------------------------------
/os-app/sub-list/i18n-es.yml:
--------------------------------------------------------------------------------
1 | ZDAGlanceListEmptyText: No hay datos
2 |
--------------------------------------------------------------------------------
/os-app/sub-list/i18n-fr.yml:
--------------------------------------------------------------------------------
1 | ZDAGlanceListEmptyText: Pas de données
2 |
--------------------------------------------------------------------------------
/os-app/sub-list/i18n-pt.yml:
--------------------------------------------------------------------------------
1 | ZDAGlanceListEmptyText: Não tem dados
2 |
--------------------------------------------------------------------------------
/os-app/sub-list/ui-test-_access.js:
--------------------------------------------------------------------------------
1 | const kDefaultRoute = require('./controller.js').OLSKControllerRoutes().shift();
2 |
3 | Object.entries({
4 | ZDAGlanceList: '.ZDAGlanceList',
5 |
6 | ZDAGlanceListEmpty: '.ZDAGlanceListEmpty',
7 |
8 | ZDAGlanceListItem: '.ZDAGlanceListItem',
9 |
10 | ZDAGlanceListItemIcon: '.ZDAGlanceListItemIcon',
11 | ZDAGlanceListItemIconImage: '.ZDAGlanceListItemIconImage',
12 | ZDAGlanceListItemName: '.ZDAGlanceListItemName',
13 | ZDAGlanceListItemBlurb: '.ZDAGlanceListItemBlurb',
14 | }).map(function (e) {
15 | return global[e.shift()] = e.pop();
16 | });
17 |
18 | describe('ZDAGlanceList_Access', function () {
19 |
20 | before(function() {
21 | return browser.OLSKVisit(kDefaultRoute);
22 | });
23 |
24 | it('shows ZDAGlanceList', function() {
25 | return browser.assert.elements(ZDAGlanceList, 1);
26 | });
27 |
28 | it('shows ZDAGlanceListEmpty', function () {
29 | return browser.assert.elements(ZDAGlanceListEmpty, 1);
30 | });
31 |
32 | it('hides ZDAGlanceListItem', function () {
33 | return browser.assert.elements(ZDAGlanceListItem, 0);
34 | });
35 |
36 | context('ZDAGlanceListData', function () {
37 |
38 | const count = Math.max(1, Date.now() % 10);
39 |
40 | before(function() {
41 | return browser.OLSKVisit(kDefaultRoute, {
42 | ZDAGlanceListData: JSON.stringify(Array.from(Array(count)).map(function (e) {
43 | return {
44 | ZDAProjectBanks: {},
45 | };
46 | })),
47 | });
48 | });
49 |
50 | it('hides ZDAGlanceListEmpty', function () {
51 | return browser.assert.elements(ZDAGlanceListEmpty, 0);
52 | });
53 |
54 | it('shows ZDAGlanceListItem', function () {
55 | return browser.assert.elements(ZDAGlanceListItem, count);
56 | });
57 |
58 | it('shows ZDAGlanceListItemIcon', function () {
59 | return browser.assert.elements(ZDAGlanceListItemIcon, count);
60 | });
61 |
62 | it('shows ZDAGlanceListItemIconImage', function () {
63 | return browser.assert.elements(ZDAGlanceListItemIconImage, count);
64 | });
65 |
66 | it('shows ZDAGlanceListItemName', function () {
67 | return browser.assert.elements(ZDAGlanceListItemName, count);
68 | });
69 |
70 | it('shows ZDAGlanceListItemBlurb', function () {
71 | return browser.assert.elements(ZDAGlanceListItemBlurb, count);
72 | });
73 |
74 | });
75 |
76 | });
77 |
--------------------------------------------------------------------------------
/os-app/sub-list/ui-test-_localize.js:
--------------------------------------------------------------------------------
1 | const kDefaultRoute = require('./controller.js').OLSKControllerRoutes().shift();
2 |
3 | kDefaultRoute.OLSKRouteLanguageCodes.forEach(function (OLSKRoutingLanguage) {
4 |
5 | const uLocalized = function (inputData) {
6 | return OLSKTestingLocalized(inputData, OLSKRoutingLanguage);
7 | };
8 |
9 | describe('ZDAGlanceList_Localize-' + OLSKRoutingLanguage, function () {
10 |
11 | before(function() {
12 | return browser.OLSKVisit(kDefaultRoute, {
13 | OLSKRoutingLanguage,
14 | });
15 | });
16 |
17 | it('localizes ZDAGlanceListEmpty', function () {
18 | return browser.assert.text(ZDAGlanceListEmpty, uLocalized('ZDAGlanceListEmptyText'));
19 | });
20 |
21 | });
22 |
23 | });
24 |
--------------------------------------------------------------------------------
/os-app/sub-list/ui-test-_misc.js:
--------------------------------------------------------------------------------
1 | const kDefaultRoute = require('./controller.js').OLSKControllerRoutes().shift();
2 |
3 | const ZDABank = require('../_shared/ZDABank/main.js');
4 |
5 | describe('ZDAGlanceList_Misc', function () {
6 |
7 | const item = {
8 | ZDAProjectName: Math.random().toString(),
9 | ZDAProjectBlurb: Math.random().toString(),
10 | ZDAProjectURL: Math.random().toString(),
11 | ZDAProjectIconURL: uRandomElement(undefined, Math.random().toString()),
12 | _ZDAProjectIconURLCachedPath: uRandomElement(undefined, Math.random().toString()),
13 | ZDAProjectBanks: Object.fromEntries(Object.entries(ZDABank.ZDABankProtocolProperties()).filter(function () {
14 | return uRandomElement(true, false);
15 | })),
16 | };
17 |
18 | before(function() {
19 | return browser.OLSKVisit(kDefaultRoute, {
20 | ZDAGlanceListData: JSON.stringify([item]),
21 | });
22 | });
23 |
24 | describe('ZDAGlanceList', function test_ZDAGlanceList () {
25 |
26 | it('sets lang', function () {
27 | return browser.assert.attribute(ZDAGlanceList, 'lang', 'en');
28 | });
29 |
30 | });
31 |
32 | describe('ZDAGlanceListItem', function test_ZDAGlanceListItem () {
33 |
34 | it('classes OLSKCommonCard', function () {
35 | return browser.assert.hasClass(ZDAGlanceListItem, 'OLSKCommonCard');
36 | });
37 |
38 | it('sets data-protocols', function () {
39 | return browser.assert.attribute('.ZDAGlanceListItem', 'data-protocols', Object.values(item.ZDAProjectBanks).filter(function (e) {
40 | return e.ZDABankProtocol;
41 | }).map(function (e) {
42 | return e.ZDABankProtocol.ZDAProtocolName;
43 | }).join(', '));
44 | });
45 |
46 | });
47 |
48 | describe('ZDAGlanceListItemIcon', function test_ZDAGlanceListItemIcon () {
49 |
50 | it('sets href', function () {
51 | return browser.assert.attribute(ZDAGlanceListItemIcon, 'href', item.ZDAProjectURL);
52 | });
53 |
54 | it('sets aria-hidden', function () {
55 | return browser.assert.attribute(ZDAGlanceListItemIcon, 'aria-hidden', 'true');
56 | });
57 |
58 | it('sets tabindex', function () {
59 | return browser.assert.attribute(ZDAGlanceListItemIcon, 'tabindex', '-1');
60 | });
61 |
62 | });
63 |
64 | describe('ZDAGlanceListItemIconImage', function test_ZDAGlanceListItemIconImage () {
65 |
66 | it('sets src', function () {
67 | return browser.assert.attribute(ZDAGlanceListItemIconImage, 'src', item._ZDAProjectIconURLCachedPath || item.ZDAProjectIconURL || '/_shared/__external/OLSKUIAssets/_OLSKSharedIconPlaceholder.svg');
68 | });
69 |
70 | });
71 |
72 | describe('ZDAGlanceListItemName', function test_ZDAGlanceListItemName () {
73 |
74 | it('sets href', function () {
75 | return browser.assert.attribute(ZDAGlanceListItemName, 'href', item.ZDAProjectURL);
76 | });
77 |
78 | it('sets target', function () {
79 | return browser.assert.attribute(ZDAGlanceListItemName, 'target', '_blank');
80 | });
81 |
82 | it('binds ZDAProjectName', function () {
83 | return browser.assert.text(ZDAGlanceListItemName, item.ZDAProjectName);
84 | });
85 |
86 | });
87 |
88 | describe('ZDAGlanceListItemBlurb', function test_ZDAGlanceListItemBlurb () {
89 |
90 | it('binds ZDAProjectBlurb', function () {
91 | return browser.assert.text(ZDAGlanceListItemBlurb, item.ZDAProjectBlurb);
92 | });
93 |
94 | });
95 |
96 | });
97 |
--------------------------------------------------------------------------------
/os-app/sub-list/ui-view.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 | <% if (!locals.ZDAGlanceListData.length) { -%>
4 |
<%= OLSKLocalized('ZDAGlanceListEmptyText') %>
5 | <% } -%>
6 |
7 |
8 |
9 | <% locals.ZDAGlanceListData.forEach(function (item) { -%>
10 |
23 | <% }) -%>
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/os-app/task-a-banks/controller-tests.js:
--------------------------------------------------------------------------------
1 | const { throws, rejects, deepEqual } = require('assert');
2 |
3 | const mod = require('./controller.js');
4 |
5 | const ZDABank = require('../_shared/ZDABank/main.js');
6 | const OLSKCache = require('OLSKCache');
7 |
8 | describe('_DataBankObjects', function test__DataBankObjects() {
9 |
10 | it('throws if param1 not in ZDABankURLs', function () {
11 | throws(function () {
12 | mod._DataBankObjects(Math.random().toString(), Math.random().toString());
13 | }, /ZDAErrorInputNotValid/);
14 | });
15 |
16 | it('throws if param2 not string', function () {
17 | throws(function () {
18 | mod._DataBankObjects(uRandomElement(ZDABank.ZDABankURLs()), null);
19 | }, /ZDAErrorInputNotValid/);
20 | });
21 |
22 | it('returns array', function () {
23 | deepEqual(mod._DataBankObjects(uRandomElement(ZDABank.ZDABankURLs()), ''), []);
24 | });
25 |
26 | context('RemoteStorage', function test_RemoteStorage () {
27 |
28 | const uBank = function (inputData = {}) {
29 | const item = Object.assign({
30 | ZDAProjectURL: Math.random().toString(),
31 | ZDABankName: Math.random().toString(),
32 | ZDABankBlurb: Math.random().toString(),
33 | }, inputData);
34 |
35 | return `${ Math.random().toString() } |
`;
36 | };
37 |
38 | it('parses data', function () {
39 | const ZDAProjectURL = Math.random().toString();
40 | const ZDABankName = Math.random().toString();
41 | const ZDABankBlurb = Math.random().toString();
42 |
43 | deepEqual(mod._DataBankObjects(ZDABank.ZDABankURLRemoteStorage(), uBank({
44 | ZDAProjectURL,
45 | ZDABankName,
46 | ZDABankBlurb,
47 | })), [{
48 | ZDAProjectURL,
49 | ZDAProjectBanks: {
50 | ZDABankRemoteStorage: {
51 | ZDABankName,
52 | ZDABankBlurb,
53 | ZDABankProtocol: ZDABank.ZDABankProtocolProperties().ZDABankRemoteStorage,
54 | },
55 | },
56 | }]);
57 | });
58 |
59 | });
60 |
61 | context('Fission', function test_Fission () {
62 |
63 | const uBank = function (inputData = {}) {
64 | const item = Object.assign({
65 | ZDAProjectURL: Math.random().toString(),
66 | ZDABankName: Math.random().toString(),
67 | ZDABankBlurb: Math.random().toString(),
68 | }, inputData);
69 |
70 | return ``;
71 | };
72 |
73 | it('parses data', function () {
74 | const ZDAProjectURL = Math.random().toString();
75 | const ZDABankName = Math.random().toString();
76 | const ZDABankBlurb = Math.random().toString();
77 |
78 | deepEqual(mod._DataBankObjects(ZDABank.ZDABankURLFission(), uBank({
79 | ZDAProjectURL,
80 | ZDABankName,
81 | ZDABankBlurb,
82 | })), [{
83 | ZDAProjectURL,
84 | ZDAProjectBanks: {
85 | ZDABankFission: {
86 | ZDABankName,
87 | ZDABankBlurb,
88 | ZDABankProtocol: ZDABank.ZDABankProtocolProperties().ZDABankFission,
89 | },
90 | },
91 | }]);
92 | });
93 |
94 | });
95 |
96 | context('Awesome', function test_Awesome () {
97 |
98 | const uBank = function (inputData = {}) {
99 | const item = Object.assign({
100 | ZDAProjectURL: Math.random().toString(),
101 | ZDABankName: Math.random().toString(),
102 | ZDABankBlurb: Math.random().toString(),
103 | }, inputData);
104 |
105 | return `# Apps\n- [${ item.ZDABankName }](${ item.ZDAProjectURL }): ${ item.ZDABankBlurb }\n\n# ` + Math.random().toString();
106 | };
107 |
108 | it('parses data', function () {
109 | const ZDAProjectURL = Math.random().toString();
110 | const ZDABankName = Math.random().toString();
111 | const ZDABankBlurb = Math.random().toString();
112 |
113 | deepEqual(mod._DataBankObjects(ZDABank.ZDABankURLAwesome(), uBank({
114 | ZDAProjectURL,
115 | ZDABankName,
116 | ZDABankBlurb,
117 | })), [{
118 | ZDAProjectURL,
119 | ZDAProjectBanks: {
120 | ZDABankAwesome: {
121 | ZDABankName,
122 | ZDABankBlurb,
123 | },
124 | },
125 | }]);
126 | });
127 |
128 | });
129 |
130 | context('Unhosted', function test_Unhosted () {
131 |
132 | const uBank = function (inputData = {}) {
133 | const item = Object.assign({
134 | ZDAProjectURL: Math.random().toString(),
135 | ZDABankName: Math.random().toString(),
136 | }, inputData);
137 |
138 | return ``;
139 | };
140 |
141 | it('parses data', function () {
142 | const ZDAProjectURL = Math.random().toString();
143 | const ZDABankName = Math.random().toString();
144 | const _ZDABankImageHREF = '/' + Math.random().toString();
145 |
146 | deepEqual(mod._DataBankObjects(ZDABank.ZDABankURLUnhosted(), uBank({
147 | ZDAProjectURL,
148 | ZDABankName,
149 | _ZDABankImageHREF,
150 | })), [{
151 | ZDAProjectURL,
152 | ZDAProjectBanks: {
153 | ZDABankUnhosted: {
154 | ZDABankName,
155 | ZDABankImageURL: require('OLSKLink').OLSKLinkRelativeURL(ZDABank.ZDABankURLUnhosted(), _ZDABankImageHREF),
156 | },
157 | },
158 | }]);
159 | });
160 |
161 | });
162 |
163 | context('SolidProject', function test_SolidProject () {
164 |
165 | const uBank = function (inputData = {}) {
166 | const item = Object.assign({
167 | ZDAProjectURL: Math.random().toString(),
168 | ZDABankName: Math.random().toString(),
169 | ZDABankBlurb: Math.random().toString(),
170 | ZDABankExtra: Math.random().toString(),
171 | }, inputData);
172 |
173 | return `${ Math.random().toString() }
${ Math.random().toString() }
${ Math.random().toString() }
${ Math.random().toString() }
Apps inclusion and exclusion criteria
${ Math.random().toString() }
`;
174 | };
175 |
176 | it('parses data', function () {
177 | const ZDAProjectURL = Math.random().toString();
178 | const ZDABankName = Math.random().toString();
179 | const ZDABankBlurb = Math.random().toString();
180 | const ZDABankExtra = Math.random().toString();
181 |
182 | deepEqual(mod._DataBankObjects(ZDABank.ZDABankURLSolidProject(), uBank({
183 | ZDAProjectURL,
184 | ZDABankName,
185 | ZDABankBlurb,
186 | ZDABankExtra,
187 | })), [{
188 | ZDAProjectURL,
189 | ZDAProjectBanks: {
190 | ZDABankSolidProject: {
191 | ZDABankName,
192 | ZDABankBlurb: [ZDABankBlurb, ZDABankExtra].join(' '),
193 | ZDABankProtocol: ZDABank.ZDABankProtocolProperties().ZDABankSolidProject,
194 | },
195 | },
196 | }]);
197 | });
198 |
199 | it('hides Copyright', function () {
200 | const ZDABankName = Math.random().toString();
201 | const ZDABankBlurb = Math.random().toString();
202 |
203 | deepEqual(mod._DataBankObjects(ZDABank.ZDABankURLSolidProject(), uBank({
204 | ZDABankName,
205 | ZDABankBlurb,
206 | ZDABankExtra: 'Copyright ' + Math.random().toString(),
207 | })).shift().ZDAProjectBanks.ZDABankSolidProject.ZDABankBlurb, [ZDABankBlurb].join(' '));
208 | });
209 |
210 | it('hides (c)', function () {
211 | const ZDABankName = Math.random().toString();
212 | const ZDABankBlurb = Math.random().toString();
213 |
214 | deepEqual(mod._DataBankObjects(ZDABank.ZDABankURLSolidProject(), uBank({
215 | ZDABankName,
216 | ZDABankBlurb,
217 | ZDABankExtra: '(c) ' + Math.random().toString(),
218 | })).shift().ZDAProjectBanks.ZDABankSolidProject.ZDABankBlurb, [ZDABankBlurb].join(' '));
219 | });
220 |
221 | it('hides . Source', function () {
222 | const ZDABankName = Math.random().toString();
223 | const ZDABankBlurb = Math.random().toString();
224 |
225 | deepEqual(mod._DataBankObjects(ZDABank.ZDABankURLSolidProject(), uBank({
226 | ZDABankName,
227 | ZDABankBlurb,
228 | ZDABankExtra: '. Source ' + Math.random().toString(),
229 | })).shift().ZDAProjectBanks.ZDABankSolidProject.ZDABankBlurb, [ZDABankBlurb].join(' '));
230 | });
231 |
232 | it('hides combination ', function () {
233 | const ZDABankName = Math.random().toString();
234 | const ZDABankBlurb = Math.random().toString();
235 |
236 | deepEqual(mod._DataBankObjects(ZDABank.ZDABankURLSolidProject(), uBank({
237 | ZDABankName,
238 | ZDABankBlurb,
239 | ZDABankExtra: 'Copyright (c) ' + Math.random().toString(),
240 | })).shift().ZDAProjectBanks.ZDABankSolidProject.ZDABankBlurb, [ZDABankBlurb].join(' '));
241 | });
242 |
243 | });
244 |
245 | });
246 |
247 | describe('_DataFilterProject', function test__DataFilterProject() {
248 |
249 | it('returns true', function () {
250 | const item = {
251 | [Math.random().toString()]: Math.random().toString(),
252 | };
253 | deepEqual(mod._DataFilterProject(item), true);
254 | });
255 |
256 | context('ZDAProjectURL', function () {
257 |
258 | [
259 | 'http://crypton.io/',
260 | 'https://peercdn.com/',
261 | 'http://cryptosphere.org/',
262 | 'https://app.solidbase.info',
263 | 'https://waves.kosmos.org/',
264 | 'https://sit.fyi',
265 | 'https://applications.linkedpipes.com/',
266 | ].forEach(function (ZDAProjectURL) {
267 |
268 | it(`filters ${ ZDAProjectURL }`, function () {
269 | deepEqual(mod._DataFilterProject({
270 | ZDAProjectURL,
271 | }), false);
272 | });
273 |
274 | });
275 |
276 | });
277 |
278 | context('ZDABankName', function () {
279 |
280 | [
281 | 'Hello World',
282 | 'Cesium',
283 | ].forEach(function (ZDABankName) {
284 |
285 | it(`filters ${ ZDABankName }`, function () {
286 | deepEqual(mod._DataFilterProject({
287 | ZDAProjectBanks: {
288 | [Math.random().toString()]: {
289 | ZDABankName,
290 | },
291 | },
292 | }), false);
293 | });
294 |
295 | });
296 |
297 | });
298 |
299 | });
300 |
301 | describe('_DataHotfixProject', function test__DataHotfixProject() {
302 |
303 | it('returns input', function () {
304 | const item = {
305 | [Math.random().toString()]: Math.random().toString(),
306 | };
307 | deepEqual(mod._DataHotfixProject(item), item);
308 | });
309 |
310 | context('ZDAProjectURL', function () {
311 |
312 | Object.entries({}).forEach(function ([key, value]) {
313 |
314 | it(`hotfixes ${ key }`, function () {
315 | deepEqual(mod._DataHotfixProject({
316 | ZDAProjectURL: key,
317 | }), {
318 | ZDAProjectURL: value,
319 | });
320 | });
321 |
322 | });
323 |
324 | });
325 |
326 | });
327 |
328 | describe('_DataMergeProjects', function test__DataMergeProjects() {
329 |
330 | const __DataMergeProjects = function (param1, param2) {
331 | const ZDAProjectURL = Math.random().toString();
332 | return mod._DataMergeProjects([Object.assign({
333 | ZDAProjectURL,
334 | }, param1), Object.assign({
335 | ZDAProjectURL,
336 | }, param2)]).map(function (e) {
337 | delete e.ZDAProjectURL;
338 |
339 | return e;
340 | });
341 | };
342 |
343 | it('throws if not array', function () {
344 | throws(function () {
345 | mod._DataMergeProjects(null);
346 | }, /ZDAErrorInputNotValid/);
347 | });
348 |
349 | it('returns input', function () {
350 | const item = {
351 | ZDAProjectURL: Math.random().toString(),
352 | };
353 | deepEqual(mod._DataMergeProjects([item]), [item]);
354 | });
355 |
356 | it('excludes if no ZDAProjectURL', function () {
357 | deepEqual(mod._DataMergeProjects([{}]), []);
358 | });
359 |
360 | it('merges if ZDAProjectURL exact', function () {
361 | const ZDAProjectURL = Math.random().toString();
362 | deepEqual(mod._DataMergeProjects([{
363 | ZDAProjectURL,
364 | }, {
365 | ZDAProjectURL,
366 | }]), [{
367 | ZDAProjectURL,
368 | }]);
369 | });
370 |
371 | it('merges if ZDAProjectURL trailing slash', function () {
372 | const ZDAProjectURL = Math.random().toString();
373 | deepEqual(mod._DataMergeProjects([{
374 | ZDAProjectURL,
375 | }, {
376 | ZDAProjectURL: ZDAProjectURL + '/',
377 | }]), [{
378 | ZDAProjectURL,
379 | }]);
380 | });
381 |
382 | it('copies properties', function () {
383 | const alfa = Math.random().toString();
384 | const bravo = Math.random().toString();
385 | deepEqual(__DataMergeProjects({
386 | alfa
387 | }, {
388 | bravo
389 | }), [{
390 | alfa,
391 | bravo
392 | }]);
393 | });
394 |
395 | it('copies ZDAProjectBanks', function () {
396 | const alfa = Math.random().toString();
397 | const bravo = Math.random().toString();
398 | deepEqual(__DataMergeProjects({
399 | ZDAProjectBanks: {
400 | alfa,
401 | },
402 | }, {
403 | ZDAProjectBanks: {
404 | bravo,
405 | },
406 | }), [{
407 | ZDAProjectBanks: {
408 | alfa,
409 | bravo,
410 | },
411 | }]);
412 | });
413 |
414 | });
415 |
416 | describe('_DataFillProjects', function test__DataFillProjects() {
417 |
418 | it('throws if not array', function () {
419 | throws(function () {
420 | mod._DataFillProjects(null);
421 | }, /ZDAErrorInputNotValid/);
422 | });
423 |
424 | it('returns input', function () {
425 | const item = {
426 | [Math.random().toString()]: Math.random().toString(),
427 | };
428 | deepEqual(mod._DataFillProjects([item]), [item]);
429 | });
430 |
431 | context('ZDAProjectName', function () {
432 |
433 | it('copies ZDABankName', function () {
434 | const ZDABankName = Math.random().toString();
435 | deepEqual(mod._DataFillProjects([{
436 | ZDAProjectBanks: {
437 | [Math.random().toString()]: {
438 | ZDABankName,
439 | },
440 | },
441 | }])[0].ZDAProjectName, ZDABankName);
442 | });
443 |
444 | it('select first ZDABankName', function () {
445 | const ZDABankName = Math.random().toString();
446 | deepEqual(mod._DataFillProjects([{
447 | ZDAProjectBanks: {
448 | [Math.random().toString()]: {
449 | ZDABankName,
450 | },
451 | [Math.random().toString()]: {
452 | ZDABankName: Math.random().toString(),
453 | },
454 | },
455 | }])[0].ZDAProjectName, ZDABankName);
456 | });
457 |
458 | });
459 |
460 | context('ZDAProjectID', function () {
461 |
462 | it('copies ZDAProjectName', function () {
463 | const ZDAProjectID = Math.random().toString();
464 | deepEqual(mod._DataFillProjects([{
465 | ZDAProjectName: ZDAProjectID,
466 | }])[0].ZDAProjectID, ZDAProjectID);
467 | });
468 |
469 | it('converts to lower case', function () {
470 | const ZDAProjectID = 'ALFA' + Math.random().toString();
471 | deepEqual(mod._DataFillProjects([{
472 | ZDAProjectName: ZDAProjectID,
473 | }])[0].ZDAProjectID, ZDAProjectID.toLowerCase());
474 | });
475 |
476 | it('replaces spaces', function () {
477 | const ZDAProjectID = 'alfa ' + Math.random().toString();
478 | deepEqual(mod._DataFillProjects([{
479 | ZDAProjectName: ZDAProjectID,
480 | }])[0].ZDAProjectID, ZDAProjectID.split(' ').join('-'));
481 | });
482 |
483 |
484 | it('throws if duplicate', function () {
485 | const ZDAProjectName = Math.random().toString();
486 | throws(function () {
487 | mod._DataFillProjects(mod._DataFillProjects([{
488 | ZDAProjectName,
489 | }, {
490 | ZDAProjectName,
491 | }]));
492 | }, /ZDAErrorInputNotValid/);
493 | });
494 |
495 | });
496 |
497 | context('ZDAProjectBlurb', function () {
498 |
499 | it('copies ZDABankBlurb', function () {
500 | const ZDABankBlurb = Math.random().toString();
501 | deepEqual(mod._DataFillProjects([{
502 | ZDAProjectBanks: {
503 | [Math.random().toString()]: {
504 | ZDABankBlurb,
505 | },
506 | },
507 | }])[0].ZDAProjectBlurb, ZDABankBlurb);
508 | });
509 |
510 | it('select first ZDABankBlurb', function () {
511 | const ZDABankBlurb = Math.random().toString();
512 | deepEqual(mod._DataFillProjects([{
513 | ZDAProjectBanks: {
514 | [Math.random().toString()]: {
515 | ZDABankBlurb,
516 | },
517 | [Math.random().toString()]: {
518 | ZDABankBlurb: Math.random().toString(),
519 | },
520 | },
521 | }])[0].ZDAProjectBlurb, ZDABankBlurb);
522 | });
523 |
524 | });
525 |
526 | context('ZDAProjectIconURL', function () {
527 |
528 | it('copies ZDABankImageURL', function () {
529 | const ZDABankImageURL = Math.random().toString();
530 | deepEqual(mod._DataFillProjects([{
531 | ZDAProjectBanks: {
532 | [Math.random().toString()]: {
533 | ZDABankImageURL,
534 | },
535 | },
536 | }])[0].ZDAProjectIconURL, ZDABankImageURL);
537 | });
538 |
539 | it('select first ZDABankImageURL', function () {
540 | const ZDABankImageURL = Math.random().toString();
541 | deepEqual(mod._DataFillProjects([{
542 | ZDAProjectBanks: {
543 | [Math.random().toString()]: {
544 | ZDABankImageURL,
545 | },
546 | [Math.random().toString()]: {
547 | ZDABankImageURL: Math.random().toString(),
548 | },
549 | },
550 | }])[0].ZDAProjectIconURL, ZDABankImageURL);
551 | });
552 |
553 | });
554 |
555 | });
556 |
557 | describe('DataBankProjects', function test_DataBankProjects() {
558 |
559 | const _DataBankProjects = function (inputData = {}) {
560 | return Object.assign(Object.assign({}, mod), {
561 | _OLSKCacheResultMap: {},
562 | _DataBankObjects: (function () {
563 | return [];
564 | }),
565 | }, inputData).DataBankProjects();
566 | };
567 |
568 | it('calls _DataBankObjects', function () {
569 | const item = [];
570 |
571 | const _OLSKCacheResultMap = ZDABank.ZDABankURLs().reduce(function (coll, item) {
572 | return Object.assign(coll, {
573 | [item]: Math.random().toString(),
574 | });
575 | }, {});
576 |
577 | _DataBankProjects({
578 | _OLSKCacheResultMap,
579 | _DataBankObjects: (function () {
580 | item.push([...arguments]);
581 |
582 | return [];
583 | }),
584 | });
585 |
586 | deepEqual(item, ZDABank.ZDABankURLs().map(function (e) {
587 | return [e, _OLSKCacheResultMap[e]];
588 | }));
589 | });
590 |
591 | it('trims properties', function () {
592 | const item = Math.random().toString();
593 | deepEqual(_DataBankProjects({
594 | _DataBankObjects: (function () {
595 | return [{
596 | ZDAProjectURL: arguments[0],
597 | [item]: ' ' + item + ' ',
598 | }];
599 | }),
600 | }), ZDABank.ZDABankURLs().reduce(function (coll, ZDAProjectURL) {
601 | return coll.concat({
602 | ZDAProjectURL,
603 | [item]: item,
604 | });
605 | }, []));
606 | });
607 |
608 | it('passes default value if cache empty', function () {
609 | deepEqual(_DataBankProjects({
610 | _DataBankObjects: mod._DataBankObjects,
611 | }), []);
612 | });
613 |
614 | it('calls _DataMergeProjects', function () {
615 | const item = Math.random().toString();
616 | deepEqual(_DataBankProjects({
617 | _DataBankObjects: (function () {
618 | return [{
619 | ZDAProjectURL: arguments[0],
620 | item,
621 | }];
622 | }),
623 | _DataMergeProjects: (function () {
624 | return [...arguments];
625 | }),
626 | }), [ZDABank.ZDABankURLs().reduce(function (coll, ZDAProjectURL) {
627 | return coll.concat({
628 | ZDAProjectURL,
629 | item,
630 | });
631 | }, [])]);
632 | });
633 |
634 | it('returns _DataFillProjects', function () {
635 | const item = {
636 | [Math.random().toString()]: Math.random().toString(),
637 | };
638 | deepEqual(_DataBankProjects({
639 | _DataMergeProjects: (function () {
640 | return [item];
641 | }),
642 | _DataFillProjects: (function () {
643 | return [...arguments].concat(item);
644 | }),
645 | }), [[item], item]);
646 | });
647 |
648 | });
649 |
650 | describe('_DataBankProtocolObjects', function test__DataBankProtocolObjects() {
651 |
652 | const uBank = function (inputData = {}) {
653 | const item = Object.assign({
654 | ZDAProtocolURL: Math.random().toString(),
655 | ZDAProtocolName: Math.random().toString(),
656 | ZDAProtocolIconURL: Math.random().toString(),
657 | }, inputData);
658 |
659 | return `# Protocols\n | \n${ item.ZDAProtocolName }\n |
\n#`;
660 | };
661 |
662 | it('throws if not string', function () {
663 | throws(function () {
664 | mod._DataBankProtocolObjects(null);
665 | }, /ZDAErrorInputNotValid/);
666 | });
667 |
668 | it('returns array', function () {
669 | deepEqual(mod._DataBankProtocolObjects(''), []);
670 | });
671 |
672 | it('parses data', function () {
673 | const ZDAProtocolURL = Math.random().toString();
674 | const ZDAProtocolName = Math.random().toString();
675 | const ZDAProtocolIconURL = Math.random().toString();
676 |
677 | deepEqual(mod._DataBankProtocolObjects(uBank({
678 | ZDAProtocolURL,
679 | ZDAProtocolName,
680 | ZDAProtocolIconURL,
681 | })), [{
682 | ZDAProtocolURL,
683 | ZDAProtocolName,
684 | ZDAProtocolIconURL,
685 | }]);
686 | });
687 |
688 | });
689 |
690 | describe('DataBankProtocols', function test_DataBankProtocols() {
691 |
692 | const _DataBankProtocols = function (inputData) {
693 | const _mod = Object.assign(Object.assign({}, mod), {
694 | _DataBankProtocolObjects: (function () {}),
695 | }, inputData);
696 | return _mod.DataBankProtocols() || _mod;
697 | };
698 |
699 | it('calls _DataBankProtocolObjects', function () {
700 | const item = Math.random().toString();
701 | deepEqual(uCapture(function (capture) {
702 | _DataBankProtocols({
703 | _OLSKCacheResultMap: {
704 | [ZDABank.ZDABankURLAwesome()]: item,
705 | },
706 | _DataBankProtocolObjects: (function () {
707 | capture(...arguments);
708 |
709 | return [];
710 | }),
711 | });
712 | }), [item]);
713 | });
714 |
715 | });
716 |
717 | describe('_DataBankToolObjects', function test__DataBankToolObjects() {
718 |
719 | const uBank = function (inputData = {}) {
720 | const item = Object.assign({
721 | ZDAToolURL: Math.random().toString(),
722 | ZDAToolName: Math.random().toString(),
723 | ZDAToolBlurb: Math.random().toString(),
724 | }, inputData);
725 |
726 | return `# Tools\n- [${ item.ZDAToolName }](${ item.ZDAToolURL }): ${ item.ZDAToolBlurb }\n#`;
727 | };
728 |
729 | it('throws if not string', function () {
730 | throws(function () {
731 | mod._DataBankToolObjects(null);
732 | }, /ZDAErrorInputNotValid/);
733 | });
734 |
735 | it('returns array', function () {
736 | deepEqual(mod._DataBankToolObjects(''), []);
737 | });
738 |
739 | it('parses data', function () {
740 | const ZDAToolURL = Math.random().toString();
741 | const ZDAToolName = Math.random().toString();
742 | const ZDAToolBlurb = Math.random().toString();
743 |
744 | deepEqual(mod._DataBankToolObjects(uBank({
745 | ZDAToolURL,
746 | ZDAToolName,
747 | ZDAToolBlurb,
748 | })), [{
749 | ZDAToolURL,
750 | ZDAToolName,
751 | ZDAToolBlurb,
752 | }]);
753 | });
754 |
755 | });
756 |
757 | describe('DataBankTools', function test_DataBankTools() {
758 |
759 | const _DataBankTools = function (inputData) {
760 | const _mod = Object.assign(Object.assign({}, mod), {
761 | _DataBankToolObjects: (function () {}),
762 | }, inputData);
763 | return _mod.DataBankTools() || _mod;
764 | };
765 |
766 | it('calls _DataBankToolObjects', function () {
767 | const item = Math.random().toString();
768 | deepEqual(uCapture(function (_DataBankToolObjects) {
769 | _DataBankTools({
770 | _OLSKCacheResultMap: {
771 | [ZDABank.ZDABankURLAwesome()]: item,
772 | },
773 | _DataBankToolObjects,
774 | });
775 | }), [item]);
776 | });
777 |
778 | });
779 |
780 | describe('_DataBankReadingObjects', function test__DataBankReadingObjects() {
781 |
782 | const uBank = function (inputData = {}) {
783 | const item = Object.assign({
784 | ZDAReadingURL: Math.random().toString(),
785 | ZDAReadingName: Math.random().toString(),
786 | ZDAReadingBlurb: Math.random().toString(),
787 | }, inputData);
788 |
789 | return `# Reading\n- [${ item.ZDAReadingName }](${ item.ZDAReadingURL }): ${ item.ZDAReadingBlurb }\n#`;
790 | };
791 |
792 | it('throws if not string', function () {
793 | throws(function () {
794 | mod._DataBankReadingObjects(null);
795 | }, /ZDAErrorInputNotValid/);
796 | });
797 |
798 | it('returns array', function () {
799 | deepEqual(mod._DataBankReadingObjects(''), []);
800 | });
801 |
802 | it('parses data', function () {
803 | const ZDAReadingURL = Math.random().toString();
804 | const ZDAReadingName = Math.random().toString();
805 | const ZDAReadingBlurb = Math.random().toString();
806 |
807 | deepEqual(mod._DataBankReadingObjects(uBank({
808 | ZDAReadingURL,
809 | ZDAReadingName,
810 | ZDAReadingBlurb,
811 | })), [{
812 | ZDAReadingURL,
813 | ZDAReadingName,
814 | ZDAReadingBlurb,
815 | }]);
816 | });
817 |
818 | });
819 |
820 | describe('DataBankReading', function test_DataBankReading() {
821 |
822 | const _DataBankReading = function (inputData) {
823 | const _mod = Object.assign(Object.assign({}, mod), {
824 | _DataBankReadingObjects: (function () {}),
825 | }, inputData);
826 | return _mod.DataBankReading() || _mod;
827 | };
828 |
829 | it('calls _DataBankReadingObjects', function () {
830 | const item = Math.random().toString();
831 | deepEqual(uCapture(function (_DataBankReadingObjects) {
832 | _DataBankReading({
833 | _OLSKCacheResultMap: {
834 | [ZDABank.ZDABankURLAwesome()]: item,
835 | },
836 | _DataBankReadingObjects,
837 | });
838 | }), [item]);
839 | });
840 |
841 | });
842 |
843 | describe('_DataBankAdjacentObjects', function test__DataBankAdjacentObjects() {
844 |
845 | const uBank = function (inputData = {}) {
846 | const item = Object.assign({
847 | ZDAAdjacentURL: Math.random().toString(),
848 | ZDAAdjacentName: Math.random().toString(),
849 | ZDAAdjacentBlurb: Math.random().toString(),
850 | }, inputData);
851 |
852 | return `# Adjacent\n- [${ item.ZDAAdjacentName }](${ item.ZDAAdjacentURL }): ${ item.ZDAAdjacentBlurb }\n#`;
853 | };
854 |
855 | it('throws if not string', function () {
856 | throws(function () {
857 | mod._DataBankAdjacentObjects(null);
858 | }, /ZDAErrorInputNotValid/);
859 | });
860 |
861 | it('returns array', function () {
862 | deepEqual(mod._DataBankAdjacentObjects(''), []);
863 | });
864 |
865 | it('parses data', function () {
866 | const ZDAAdjacentURL = Math.random().toString();
867 | const ZDAAdjacentName = Math.random().toString();
868 | const ZDAAdjacentBlurb = Math.random().toString();
869 |
870 | deepEqual(mod._DataBankAdjacentObjects(uBank({
871 | ZDAAdjacentURL,
872 | ZDAAdjacentName,
873 | ZDAAdjacentBlurb,
874 | })), [{
875 | ZDAAdjacentURL,
876 | ZDAAdjacentName,
877 | ZDAAdjacentBlurb,
878 | }]);
879 | });
880 |
881 | });
882 |
883 | describe('DataBankAdjacent', function test_DataBankAdjacent() {
884 |
885 | const _DataBankAdjacent = function (inputData) {
886 | const _mod = Object.assign(Object.assign({}, mod), {
887 | _DataBankAdjacentObjects: (function () {}),
888 | }, inputData);
889 | return _mod.DataBankAdjacent() || _mod;
890 | };
891 |
892 | it('calls _DataBankAdjacentObjects', function () {
893 | const item = Math.random().toString();
894 | deepEqual(uCapture(function (_DataBankAdjacentObjects) {
895 | _DataBankAdjacent({
896 | _OLSKCacheResultMap: {
897 | [ZDABank.ZDABankURLAwesome()]: item,
898 | },
899 | _DataBankAdjacentObjects,
900 | });
901 | }), [item]);
902 | });
903 |
904 | });
905 |
906 | describe('_SetupBank', function test__SetupBank() {
907 |
908 | const __SetupBank = function (inputData) {
909 | return Object.assign(Object.assign({}, mod), {
910 | _DataContentJSON: (function () {}),
911 |
912 | _DataFoilOLSKCache: Object.assign({
913 | OLSKCacheQueuedFetch: (function () {}),
914 | }, inputData),
915 |
916 | _DataFoilOLSKDisk: Object.assign({
917 | OLSKDiskWrite: (function () {}),
918 | }, inputData),
919 | }, inputData)._SetupBank(inputData.ParamKey || Math.random().toString());
920 | };
921 |
922 | it('calls OLSKCacheQueuedFetch', function () {
923 | const ParamKey = Math.random().toString();
924 | const OLSKDisk = {};
925 | const item = (uCapture(function (OLSKCacheQueuedFetch) {
926 | __SetupBank({
927 | ParamKey,
928 |
929 | OLSKCacheQueuedFetch,
930 | _DataFoilOLSKDisk: OLSKDisk,
931 | });
932 | })).pop();
933 |
934 | deepEqual(item, {
935 | ParamMod: mod,
936 | ParamKey,
937 | ParamCallback: item.ParamCallback,
938 | ParamInterval: 1000 * 60 * 60 * 24,
939 | ParamFileURLs: ZDABank.ZDABankURLs(),
940 | ParamFileDirectory: __dirname,
941 | OLSKQueue: require('OLSKQueue'),
942 | OLSKDisk,
943 | });
944 | });
945 |
946 | context('ParamCallback', function () {
947 |
948 | it('calls _DataContentString', async function () {
949 | const ParamKey = Math.random().toString();
950 | deepEqual(await __SetupBank({
951 | ParamKey,
952 | OLSKCacheQueuedFetch: (function (inputData) {
953 | return inputData.ParamCallback();
954 | }),
955 | _DataContentString: (function () {
956 | return [...arguments];
957 | }),
958 | }), [ParamKey]);
959 | });
960 |
961 | });
962 |
963 | });
964 |
965 | describe('SetupBanks', function test_SetupBanks() {
966 |
967 | const _SetupBanks = function (inputData = {}) {
968 | return Object.assign(Object.assign({}, mod), {
969 | _SetupBank: (function () {}),
970 | }, inputData).SetupBanks();
971 | };
972 |
973 | it('calls _SetupBank', async function () {
974 | deepEqual(await _SetupBanks({
975 | _SetupBank: (function (e) {
976 | return e;
977 | }),
978 | }), ZDABank.ZDABankURLs());
979 | });
980 |
981 | });
982 |
--------------------------------------------------------------------------------
/os-app/task-a-banks/controller.js:
--------------------------------------------------------------------------------
1 | const cheerio = require('cheerio');
2 | const OLSKCache = require('OLSKCache');
3 | const ZDABank = require('../_shared/ZDABank/main.js');
4 |
5 | const mod = {
6 |
7 | OLSKControllerTasks () {
8 | return [{
9 | OLSKTaskName: 'ZDABanksStartFetch',
10 | OLSKTaskFireTimeInterval: 1,
11 | OLSKTaskShouldBePerformed () {
12 | return true;
13 | },
14 | OLSKTaskCallback: (function () {
15 | require('OLSKModule').OLSKModuleLifecycleSetup(mod);
16 | }),
17 | OLSKTaskFireLimit: 1,
18 | }];
19 | },
20 |
21 | OLSKControllerSharedLocals () {
22 | return {
23 | ZDAGlanceProjectsCount () {
24 | return mod.DataBankProjects().length;
25 | },
26 | ZDAProtocols () {
27 | return mod.DataBankProtocols();
28 | },
29 | ZDATools () {
30 | return mod.DataBankTools();
31 | },
32 | ZDAReading () {
33 | return mod.DataBankReading();
34 | },
35 | ZDAAdjacent () {
36 | return mod.DataBankAdjacent();
37 | },
38 | };
39 | },
40 |
41 | // DATA
42 |
43 | _DataFoilOLSKCache: OLSKCache,
44 | _DataFoilOLSKQueue: require('OLSKQueue'),
45 | _DataFoilOLSKDisk: require('OLSKDisk'),
46 | _DataFoilFS: require('fs'),
47 | _DataFoilImages: require('../task-c-images/controller.js'),
48 |
49 | async _DataContentString (inputData) {
50 | return (await require('node-fetch')(inputData)).text();
51 | },
52 |
53 | _DataBankObjects (param1, param2) {
54 | if (!ZDABank.ZDABankURLs().includes(param1)) {
55 | throw new Error('ZDAErrorInputNotValid');
56 | }
57 |
58 | if (typeof param2 !== 'string') {
59 | throw new Error('ZDAErrorInputNotValid');
60 | }
61 |
62 | return Array.from(ZDABank.ZDABankURLs().reduce(function (coll, item) {
63 | return Object.assign(coll, {
64 | [item]: {
65 | [ZDABank.ZDABankURLRemoteStorage()]: function () {
66 | return cheerio('.main-content table:not(last-of-type)', param2).find('tbody tr').map(function () {
67 | return {
68 | ZDAProjectURL: cheerio('td:nth-child(1) a', this).attr('href'),
69 | ZDAProjectBanks: {
70 | ZDABankRemoteStorage: {
71 | ZDABankName: cheerio('td:nth-child(1)', this).text(),
72 | ZDABankBlurb: cheerio('td:nth-child(2)', this).text(),
73 | ZDABankProtocol: ZDABank.ZDABankProtocolProperties().ZDABankRemoteStorage,
74 | },
75 | },
76 | };
77 | });
78 | },
79 | [ZDABank.ZDABankURLFission()]: function () {
80 | return cheerio('.entry-content', param2).first().find('li').map(function () {
81 | return {
82 | ZDAProjectURL: cheerio('a', this).attr('href'),
83 | ZDAProjectBanks: {
84 | ZDABankFission: {
85 | ZDABankName: cheerio('a', this).text(),
86 | ZDABankBlurb: cheerio(this).text().split(': ').pop(),
87 | ZDABankProtocol: ZDABank.ZDABankProtocolProperties().ZDABankFission,
88 | },
89 | },
90 | };
91 | });
92 | },
93 | [ZDABank.ZDABankURLAwesome()]: function () {
94 | return param2.split('# Apps').pop().split('#').shift().trim().split('\n-').filter(function (e) {
95 | return !!e;
96 | }).map(function (e) {
97 | return {
98 | ZDAProjectURL: e.match(/\(.*\)/)[0].slice(1, -1),
99 | ZDAProjectBanks: {
100 | ZDABankAwesome: {
101 | ZDABankName: e.match(/\[.*\]/)[0].slice(1, -1),
102 | ZDABankBlurb: e.split(': ').pop(),
103 | },
104 | },
105 | };
106 | });
107 | },
108 | [ZDABank.ZDABankURLUnhosted()]: function () {
109 | return cheerio('.icons', param2).first().find('li').map(function () {
110 | return {
111 | ZDAProjectURL: cheerio('a', this).attr('href'),
112 | ZDAProjectBanks: {
113 | ZDABankUnhosted: Object.assign({
114 | ZDABankName: cheerio('a', this).text(),
115 | }, (function(inputData) {
116 | if (!inputData) {
117 | return {};
118 | }
119 |
120 | return {
121 | ZDABankImageURL: require('OLSKLink').OLSKLinkRelativeURL(item, inputData),
122 | };
123 | })(cheerio('img', this).attr('src'))),
124 | },
125 | };
126 | });
127 | },
128 | [ZDABank.ZDABankURLSolidProject()]: function () {
129 | return cheerio('article', param2).first().find('table:not(#pod-management~table):not(#historical-solid-apps~ul>li>table) tbody tr').map(function () {
130 | return {
131 | ZDAProjectURL: cheerio('td:nth-child(1) a', this).attr('href') || '',
132 | ZDAProjectBanks: {
133 | ZDABankSolidProject: {
134 | ZDABankName: cheerio('td:nth-child(1) a', this).text(),
135 | ZDABankBlurb: (function(blurb) {
136 | if (blurb.includes('(c) ')) {
137 | blurb = blurb.slice(0, blurb.indexOf('(c) '));
138 | }
139 |
140 | if (blurb.includes('Copyright ')) {
141 | blurb = blurb.slice(0, blurb.indexOf('Copyright '));
142 | }
143 |
144 | if (blurb.includes('. Source ')) {
145 | blurb = blurb.slice(0, blurb.indexOf('. Source '));
146 | }
147 |
148 | return blurb;
149 | })(cheerio('td:nth-child(2)', this).text()).trim(),
150 | ZDABankProtocol: ZDABank.ZDABankProtocolProperties().ZDABankSolidProject,
151 | },
152 | },
153 | };
154 | });
155 | },
156 | }[item],
157 | });
158 | }, {})[param1]()).map(function (e) {
159 | return Object.fromEntries(Object.entries(e).map(function (e) {
160 | return e.map(function (e) {
161 | if (typeof e !== 'string') {
162 | return e;
163 | }
164 |
165 | return e.trim();
166 | });
167 | }));
168 | });
169 | },
170 |
171 | _DataFilterProject (e) {
172 | if (e.ZDAProjectBanks && Object.values(e.ZDAProjectBanks).filter(function (e) {
173 | return [
174 | 'Hello World',
175 | 'Cesium',
176 | ].includes(e.ZDABankName);
177 | }).length) {
178 | return false;
179 | }
180 |
181 | if ([
182 | 'http://crypton.io/',
183 | 'https://peercdn.com/',
184 | 'http://cryptosphere.org/',
185 | 'https://app.solidbase.info',
186 | 'https://waves.kosmos.org/',
187 | 'https://sit.fyi',
188 | 'https://applications.linkedpipes.com/',
189 | ].includes(e.ZDAProjectURL)) {
190 | return false;
191 | }
192 |
193 | return true;
194 | },
195 |
196 | _DataHotfixProject (e) {
197 | Object.entries({
198 | ZDAProjectURL: {},
199 | }).forEach(function ([key, changes]) {
200 | Object.entries(changes).forEach(function ([source, destination]) {
201 | if (e[key] === source) {
202 | e[key] = destination;
203 | }
204 | });
205 | });
206 |
207 | return e;
208 | },
209 |
210 | _DataMergeProjects (inputData) {
211 | if (!Array.isArray(inputData)) {
212 | throw new Error('ZDAErrorInputNotValid');
213 | }
214 |
215 | return Object.values(inputData.filter(mod._DataFilterProject).reduce(function (coll, item) {
216 | mod._DataHotfixProject(item);
217 |
218 | let id = require('OLSKLink').OLSKLinkCompareURL(item.ZDAProjectURL || '');
219 |
220 | const match = coll[id || Math.random().toString()] || {};
221 |
222 | if (match.ZDAProjectURL) {
223 | id = require('OLSKLink').OLSKLinkCompareURL(item.ZDAProjectURL = match.ZDAProjectURL);
224 | }
225 |
226 | if (!id) {
227 | return coll;
228 | }
229 |
230 | const ZDAProjectBanks = Object.assign(match.ZDAProjectBanks || {}, item.ZDAProjectBanks || {});
231 |
232 | return Object.assign(coll, {
233 | [id]: Object.assign(item, Object.assign(match, item), match.ZDAProjectBanks ? {
234 | ZDAProjectBanks,
235 | } : {}),
236 | });
237 | }, {}));
238 | },
239 |
240 | _DataFillProjects (inputData) {
241 | if (!Array.isArray(inputData)) {
242 | throw new Error('ZDAErrorInputNotValid');
243 | }
244 |
245 | const ids = [];
246 |
247 | return inputData.map(function (e) {
248 | return Object.assign(e, Object.entries({
249 | ZDABankName: 'ZDAProjectName',
250 | ZDABankBlurb: 'ZDAProjectBlurb',
251 | ZDABankImageURL: 'ZDAProjectIconURL',
252 | }).reduce(function (coll, [source, destination]) {
253 | const raw = Object.values(e.ZDAProjectBanks || {}).map(function (e) {
254 | return e[source];
255 | }).filter(function (e) {
256 | return !!e;
257 | });
258 | const data = raw[0];
259 |
260 | if (data) {
261 | coll[destination] = destination === 'ZDAProjectTags' ? mod.__DataTidyTags((coll[destination] || []).concat(...raw)) : data;
262 | }
263 |
264 | return coll;
265 | }, {}));
266 | }).map(function (e) {
267 | return Object.assign(e, e.ZDAProjectName ? {
268 | ZDAProjectID: (function(inputData) {
269 | if (ids.includes(inputData)) {
270 | throw new Error('ZDAErrorInputNotValid');
271 | }
272 |
273 | ids.push(inputData);
274 |
275 | return inputData;
276 | })(e.ZDAProjectName.toLowerCase().split(' ').join('-')),
277 | } : {});
278 | });
279 | },
280 |
281 | DataBankProjects () {
282 | if (process.env.OLSK_FLAG_CI || process.env.OLSK_SPEC_MOCHA_INTERFACE) {
283 | return [];
284 | }
285 |
286 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
287 |
288 | return _mod._DataFillProjects(_mod._DataMergeProjects(ZDABank.ZDABankURLs().reduce(function (coll, item) {
289 | return coll.concat(_mod._DataBankObjects(item, _mod._OLSKCacheResultMap[item] || '').map(require('OLSKObject').OLSKObjectTrim));
290 | }, [])));
291 | },
292 |
293 | _DataBankProtocolObjects (inputData) {
294 | if (typeof inputData !== 'string') {
295 | throw new Error('ZDAErrorInputNotValid');
296 | }
297 |
298 | return Array.from(cheerio('table', inputData.split('# Protocols').pop().split('#').shift().trim()).first().find('tr').map(function () {
299 | return {
300 | ZDAProtocolURL: cheerio('a', this).attr('href'),
301 | ZDAProtocolName: cheerio('td:nth-child(2)', this).text().trim(),
302 | ZDAProtocolIconURL: cheerio('img', this).attr('src'),
303 | };
304 | }));
305 | },
306 |
307 | DataBankProtocols () {
308 | if (process.env.OLSK_FLAG_CI || process.env.OLSK_SPEC_MOCHA_INTERFACE) {
309 | return [];
310 | }
311 |
312 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
313 |
314 | return _mod._DataBankProtocolObjects(_mod._OLSKCacheResultMap[ZDABank.ZDABankURLAwesome()]).map(function (e) {
315 | return Object.assign(e, {
316 | _ZDAProtocolIconURLCachedPath: _mod._DataFoilImages.DataCacheLocalPath(e.ZDAProtocolIconURL),
317 | });
318 | });
319 | },
320 |
321 | _DataBankToolObjects (inputData) {
322 | if (typeof inputData !== 'string') {
323 | throw new Error('ZDAErrorInputNotValid');
324 | }
325 |
326 | return inputData.split('# Tools').pop().split('#').shift().trim().split('\n-').filter(function (e) {
327 | return !!e;
328 | }).map(function (e) {
329 | return {
330 | ZDAToolURL: e.match(/\(.*\)/)[0].slice(1, -1),
331 | ZDAToolName: e.match(/\[.*\]/)[0].slice(1, -1),
332 | ZDAToolBlurb: e.split(': ').pop(),
333 | };
334 | });
335 | },
336 |
337 | DataBankTools () {
338 | if (process.env.OLSK_FLAG_CI || process.env.OLSK_SPEC_MOCHA_INTERFACE) {
339 | return [];
340 | }
341 |
342 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
343 |
344 | return _mod._DataBankToolObjects(_mod._OLSKCacheResultMap[ZDABank.ZDABankURLAwesome()]);
345 | },
346 |
347 | _DataBankReadingObjects (inputData) {
348 | if (typeof inputData !== 'string') {
349 | throw new Error('ZDAErrorInputNotValid');
350 | }
351 |
352 | return inputData.split('# Reading').pop().split('#').shift().trim().split('\n-').filter(function (e) {
353 | return !!e;
354 | }).map(function (e) {
355 | return {
356 | ZDAReadingURL: e.match(/\(.*\)/)[0].slice(1, -1),
357 | ZDAReadingName: e.match(/\[.*\]/)[0].slice(1, -1),
358 | ZDAReadingBlurb: e.split(': ').pop(),
359 | };
360 | });
361 | },
362 |
363 | DataBankReading () {
364 | if (process.env.OLSK_FLAG_CI || process.env.OLSK_SPEC_MOCHA_INTERFACE) {
365 | return [];
366 | }
367 |
368 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
369 |
370 | return _mod._DataBankReadingObjects(_mod._OLSKCacheResultMap[ZDABank.ZDABankURLAwesome()]);
371 | },
372 |
373 | _DataBankAdjacentObjects (inputData) {
374 | if (typeof inputData !== 'string') {
375 | throw new Error('ZDAErrorInputNotValid');
376 | }
377 |
378 | return inputData.split('# Adjacent').pop().split('#').shift().trim().split('\n-').filter(function (e) {
379 | return !!e;
380 | }).map(function (e) {
381 | return {
382 | ZDAAdjacentURL: e.match(/\(.*\)/)[0].slice(1, -1),
383 | ZDAAdjacentName: e.match(/\[.*\]/)[0].slice(1, -1),
384 | ZDAAdjacentBlurb: e.split(': ').pop(),
385 | };
386 | });
387 | },
388 |
389 | DataBankAdjacent () {
390 | if (process.env.OLSK_FLAG_CI || process.env.OLSK_SPEC_MOCHA_INTERFACE) {
391 | return [];
392 | }
393 |
394 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
395 |
396 | return _mod._DataBankAdjacentObjects(_mod._OLSKCacheResultMap[ZDABank.ZDABankURLAwesome()]);
397 | },
398 |
399 | // SETUP
400 |
401 | _SetupBank (inputData) {
402 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
403 |
404 | return _mod._DataFoilOLSKCache.OLSKCacheQueuedFetch({
405 | ParamMod: mod,
406 | ParamKey: inputData,
407 | ParamCallback: (function () {
408 | return _mod._DataContentString(inputData);
409 | }),
410 | ParamInterval: 1000 * 60 * 60 * 24,
411 | ParamFileURLs: ZDABank.ZDABankURLs(),
412 | ParamFileDirectory: __dirname,
413 | OLSKQueue: _mod._DataFoilOLSKQueue,
414 | OLSKDisk: _mod._DataFoilOLSKDisk,
415 | });
416 | },
417 |
418 | SetupBanks () {
419 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
420 |
421 | return Promise.all(ZDABank.ZDABankURLs().map(_mod._SetupBank));
422 | },
423 |
424 | };
425 |
426 | Object.assign(exports, mod);
427 |
--------------------------------------------------------------------------------
/os-app/task-b-details/controller-tests.js:
--------------------------------------------------------------------------------
1 | const { throws, rejects, deepEqual } = require('assert');
2 |
3 | const mod = require('./controller.js');
4 |
5 | const { JSDOM } = require('jsdom');
6 | const OLSKLink = require('OLSKLink');
7 | const OLSKCache = require('OLSKCache');
8 |
9 | describe('DataCacheAggregateBasename', function test_DataCacheAggregateBasename() {
10 |
11 | it('returns string', function () {
12 | deepEqual(mod.DataCacheAggregateBasename(), '_aggregate');
13 | });
14 |
15 | });
16 |
17 | describe('DataCacheImageAttributeCandidates', function test_DataCacheImageAttributeCandidates() {
18 |
19 | it('returns array', function () {
20 | deepEqual(mod.DataCacheImageAttributeCandidates(), [
21 | 'apple-touch-icon',
22 | 'apple-touch-icon-precomposed',
23 | 'mask-icon',
24 | ]);
25 | });
26 |
27 | });
28 |
29 | describe('_DataDOMPropertyCandidates', function test__DataDOMPropertyCandidates() {
30 |
31 | const __DataDOMPropertyCandidates = function (inputData = {}) {
32 | return mod._DataDOMPropertyCandidates(Object.assign({
33 | ParamURL: uLink(),
34 | ParamMetadata: {},
35 | }, inputData));
36 | };
37 |
38 | it('throws if not object', function () {
39 | throws(function () {
40 | mod._DataDOMPropertyCandidates(null);
41 | }, /ZDRErrorInputNotValid/);
42 | });
43 |
44 | it('throws if ParamURL not string', function () {
45 | throws(function () {
46 | __DataDOMPropertyCandidates({
47 | ParamURL: null,
48 | });
49 | }, /ZDRErrorInputNotValid/);
50 | });
51 |
52 | it('throws if ParamMetadata not object', function () {
53 | throws(function () {
54 | __DataDOMPropertyCandidates({
55 | ParamMetadata: null,
56 | });
57 | }, /ZDRErrorInputNotValid/);
58 | });
59 |
60 | it('returns array', function () {
61 | deepEqual(__DataDOMPropertyCandidates(), []);
62 | });
63 |
64 | it('throws if ParamManifest not object', function () {
65 | throws(function () {
66 | __DataDOMPropertyCandidates({
67 | ParamManifest: null,
68 | });
69 | }, /ZDRErrorInputNotValid/);
70 | });
71 |
72 | context('ParamMetadata', function () {
73 |
74 | mod.DataCacheImageAttributeCandidates().forEach(function (e) {
75 |
76 | it(`extracts ${ e }`, function () {
77 | const path = uRandomElement('https://alfa.bravo/', Math.random().toString());
78 | const ParamURL = 'https://example.com';
79 | deepEqual(__DataDOMPropertyCandidates({
80 | ParamMetadata: {
81 | [e]: path,
82 | },
83 | ParamURL,
84 | }), Object.entries({
85 | ZDAProjectIconURL: OLSKLink.OLSKLinkRelativeURL(ParamURL, path),
86 | }));
87 | });
88 |
89 | });
90 |
91 | it('extracts og:image', function () {
92 | const path = uRandomElement('https://alfa.bravo/', Math.random().toString());
93 | const ParamURL = 'https://example.com';
94 | deepEqual(__DataDOMPropertyCandidates({
95 | ParamMetadata: {
96 | 'og:image': path,
97 | },
98 | ParamURL,
99 | }), Object.entries({
100 | _ZDAProjectIconURL: OLSKLink.OLSKLinkRelativeURL(ParamURL, path),
101 | }));
102 | });
103 |
104 | it('extracts ParamManifest.description', function () {
105 | const ZDAProjectBlurb = Math.random().toString();
106 | deepEqual(__DataDOMPropertyCandidates({
107 | ParamManifest: {
108 | 'description': ZDAProjectBlurb,
109 | },
110 | }), Object.entries({
111 | ZDAProjectBlurb,
112 | ZDAProjectHasManifest: true,
113 | }));
114 | });
115 |
116 | it('extracts description', function () {
117 | const _ZDAProjectBlurb = Math.random().toString();
118 | deepEqual(__DataDOMPropertyCandidates({
119 | ParamMetadata: {
120 | 'description': _ZDAProjectBlurb,
121 | },
122 | }), Object.entries({
123 | _ZDAProjectBlurb,
124 | }));
125 | });
126 |
127 | it('extracts title', function () {
128 | const _ZDAProjectBlurb = Math.random().toString();
129 | deepEqual(__DataDOMPropertyCandidates({
130 | ParamMetadata: {
131 | 'title': _ZDAProjectBlurb,
132 | },
133 | }), Object.entries({
134 | _ZDAProjectBlurb,
135 | }));
136 | });
137 |
138 | it('extracts _OLSKDOMMetadataFunding', function () {
139 | const _OLSKDOMMetadataFunding = [Math.random().toString()];
140 | deepEqual(__DataDOMPropertyCandidates({
141 | ParamMetadata: {
142 | _OLSKDOMMetadataFunding,
143 | },
144 | }), Object.entries({
145 | ZDAProjectFunding: _OLSKDOMMetadataFunding,
146 | }));
147 | });
148 |
149 | });
150 |
151 | context('ParamManifest', function () {
152 |
153 | it('sets ZDAProjectHasManifest', function () {
154 | const ZDAProjectIconURL = uLink();
155 | deepEqual(__DataDOMPropertyCandidates({
156 | ParamManifest: {},
157 | }), Object.entries({
158 | ZDAProjectHasManifest: true,
159 | }));
160 | });
161 |
162 | it('extracts icons', function () {
163 | const ZDAProjectIconURL = uLink();
164 | deepEqual(__DataDOMPropertyCandidates({
165 | ParamManifest: {
166 | 'icons': [{
167 | src: uLink(),
168 | }, {
169 | src: ZDAProjectIconURL,
170 | }],
171 | },
172 | }), Object.entries({
173 | ZDAProjectIconURL,
174 | ZDAProjectHasManifest: true,
175 | }));
176 | });
177 |
178 | });
179 |
180 | });
181 |
182 | describe('SetupFetchQueue', function test_SetupFetchQueue() {
183 |
184 | const _SetupFetchQueue = function (inputData) {
185 | const _mod = Object.assign(Object.assign({}, mod), {
186 | _DataFoilOLSKQueue: inputData,
187 | }, inputData);
188 | return _mod.SetupFetchQueue() || _mod;
189 | };
190 |
191 | it('calls OLSKQueueAPI', function () {
192 | const item = Math.random().toString();
193 | deepEqual(_SetupFetchQueue({
194 | OLSKQueueAPI: (function () {
195 | return [...arguments].concat(item);
196 | }),
197 | })._ValueFetchQueue, [item]);
198 | });
199 |
200 | it('sets _ValueFetchQueue', function () {
201 | const item = Math.random().toString();
202 |
203 | deepEqual(_SetupFetchQueue({
204 | OLSKQueueAPI: (function () {
205 | return item;
206 | }),
207 | })._ValueFetchQueue, item);
208 | });
209 |
210 | });
211 |
212 | describe('SetupCacheObject', function test_SetupDetailCache() {
213 |
214 | const _SetupDetailCache = function (inputData) {
215 | const _mod = Object.assign(Object.assign({}, mod), {
216 | _DataFoilOLSKCache: Object.assign({
217 | OLSKCacheReadFile: (function () {}),
218 | }, inputData),
219 | });
220 | return _mod.SetupCacheObject() || _mod;
221 | };
222 |
223 | it('calls OLSKCacheReadFile', function () {
224 | const items = [];
225 |
226 | _SetupDetailCache({
227 | OLSKCacheReadFile: (function () {
228 | items.push(...arguments);
229 | }),
230 | });
231 |
232 | deepEqual(items, [mod.DataCacheAggregateBasename(), require('path').join(__dirname, '__cached')]);
233 | });
234 |
235 | it('sets _ValueCandidatesCache', function () {
236 | const OLSKCacheReadFile = uRandomElement(Math.random().toString(), null);
237 |
238 | deepEqual(_SetupDetailCache({
239 | OLSKCacheReadFile: (function () {
240 | return OLSKCacheReadFile;
241 | }),
242 | })._ValueCandidatesCache, OLSKCacheReadFile || {});
243 | });
244 |
245 | });
246 |
247 | describe('_SetupCandidates', function test__SetupCandidates() {
248 |
249 | const __SetupCandidates = function (inputData) {
250 | return Object.assign(Object.assign({}, mod), {
251 | _DataContentString: (function () {
252 | return inputData.ParamHTML;
253 | }),
254 | _DataFoilOLSKDisk: Object.assign({
255 | OLSKDiskWrite: (function () {
256 | return [...arguments].pop();
257 | }),
258 | }, inputData),
259 | }, inputData)._SetupCandidates(inputData.ParamURL || Math.random().toString());
260 | };
261 |
262 | it('calls _DataContentString', function () {
263 | const ParamURL = uLink();
264 |
265 | deepEqual(uCapture(function (_DataContentString) {
266 | __SetupCandidates({
267 | ParamURL,
268 | _DataContentString,
269 | });
270 | }), [ParamURL]);
271 | });
272 |
273 | it('calls OLSKDiskWrite', async function () {
274 | const ParamURL = uLink();
275 | const ParamHTML = Math.random().toString();
276 |
277 | deepEqual(await new Promise(function (res) {
278 | return __SetupCandidates({
279 | ParamURL,
280 | _DataContentString: (function () {
281 | return ParamHTML;
282 | }),
283 | OLSKDiskWrite: (function () {
284 | res([...arguments]);
285 | }),
286 | });
287 | }), [OLSKCache.OLSKCachePath(__dirname, OLSKCache.OLSKCacheURLBasename(ParamURL)), ParamHTML]);
288 | });
289 |
290 | it('returns _DataDOMPropertyCandidates', async function () {
291 | const ParamURL = uLink();
292 | const ParamHTML = `${ Math.random().toString() }`;
293 | deepEqual(await __SetupCandidates({
294 | ParamURL,
295 | ParamHTML,
296 | _DataDOMPropertyCandidates: (function () {
297 | return [
298 | ['arguments', [...arguments]],
299 | ];
300 | }),
301 | }), {
302 | arguments: [{
303 | ParamMetadata: require('OLSKDOM').OLSKDOMMetadata(ParamHTML, {
304 | JSDOM: JSDOM.fragment,
305 | }),
306 | ParamURL,
307 | ParamManifest: undefined,
308 | }],
309 | });
310 | });
311 |
312 | context('manifest', function () {
313 |
314 | const ParamURL = uLink();
315 | const manifest = '/manifest' + Math.random().toString();
316 | const ParamHTML = ``;
317 | const ParamManifest = {
318 | [Math.random().toString()]: Math.random().toString(),
319 | };
320 |
321 | it('calls _DataContentString', async function () {
322 | const items = [];
323 |
324 | await __SetupCandidates({
325 | ParamURL,
326 | _DataContentString: (function () {
327 | items.push(...arguments);
328 |
329 | return ParamHTML;
330 | }),
331 | });
332 |
333 | deepEqual(items, [ParamURL, OLSKLink.OLSKLinkRelativeURL(ParamURL, manifest)]);
334 | });
335 |
336 | it('calls OLSKDiskWrite', async function () {
337 | const items = [];
338 |
339 | await __SetupCandidates({
340 | ParamURL,
341 | _DataContentString: (function (inputData) {
342 | return inputData === ParamURL ? ParamHTML : JSON.stringify(ParamManifest);
343 | }),
344 | OLSKDiskWrite: (function (param1, param2) {
345 | items.push([...arguments]);
346 |
347 | return param2;
348 | }),
349 | });
350 |
351 | deepEqual(items, [
352 | [OLSKCache.OLSKCachePath(__dirname, OLSKCache.OLSKCacheURLBasename(ParamURL)),
353 | ParamHTML],
354 | [OLSKCache.OLSKCachePath(__dirname, OLSKCache.OLSKCacheURLBasename(OLSKLink.OLSKLinkRelativeURL(ParamURL, manifest))), JSON.stringify(ParamManifest)],
355 | ]);
356 | });
357 |
358 | it('returns _DataDOMPropertyCandidates', async function () {
359 | deepEqual(await __SetupCandidates({
360 | ParamURL,
361 | _DataContentString: (function (inputData) {
362 | return inputData === ParamURL ? ParamHTML : JSON.stringify(ParamManifest);
363 | }),
364 | _DataDOMPropertyCandidates: (function () {
365 | return [
366 | ['arguments', [...arguments]],
367 | ];
368 | }),
369 | }), {
370 | arguments: [{
371 | ParamMetadata: require('OLSKDOM').OLSKDOMMetadata(ParamHTML, {
372 | JSDOM: JSDOM.fragment,
373 | }),
374 | ParamURL,
375 | ParamManifest,
376 | }],
377 | });
378 | });
379 |
380 | });
381 |
382 | });
383 |
384 | describe('_SetupDetail', function test__SetupDetail() {
385 |
386 | const __SetupDetail = function (inputData) {
387 | return Object.assign(Object.assign({}, mod), {
388 | _ValueFetchQueue: Object.assign({}, inputData),
389 | _DataFoilOLSKCache: Object.assign({
390 | OLSKCacheResultFetchRenew: (function () {}),
391 | OLSKCacheWriteFile: (function () {}),
392 | }, inputData),
393 | _SetupCandidates: (function () {}),
394 | }, inputData)._SetupDetail(inputData.url || Math.random().toString());
395 | };
396 |
397 | it('calls OLSKCacheResultFetchRenew', function () {
398 | const url = Math.random().toString();
399 | const _ValueCandidatesCache = {
400 | [Math.random().toString()]: Math.random().toString(),
401 | };
402 |
403 | const item = __SetupDetail({
404 | url,
405 | _ValueCandidatesCache,
406 | OLSKCacheResultFetchRenew: (function () {
407 | return [...arguments];
408 | }),
409 | }).pop();
410 |
411 | deepEqual(item, {
412 | ParamMap: _ValueCandidatesCache,
413 | ParamKey: url,
414 | ParamCallback: item.ParamCallback,
415 | ParamInterval: 1000 * 60 * 60 * 24,
416 | _ParamCallbackDidFinish: item._ParamCallbackDidFinish,
417 | });
418 | });
419 |
420 | context('ParamCallback', function () {
421 |
422 | it('calls OLSKQueueAdd', async function () {
423 | deepEqual(await __SetupDetail({
424 | OLSKCacheResultFetchRenew: (function (inputData) {
425 | return inputData.ParamCallback();
426 | }),
427 | OLSKQueueAdd: (function () {
428 | return [...arguments].map(function (e) {
429 | return typeof e;
430 | });
431 | }),
432 | }), ['function']);
433 | });
434 |
435 | it('calls _SetupCandidates', async function () {
436 | const url = Math.random().toString();
437 |
438 | deepEqual(await __SetupDetail({
439 | url,
440 | OLSKCacheResultFetchRenew: (function (inputData) {
441 | return inputData.ParamCallback();
442 | }),
443 | OLSKQueueAdd: (function (inputData) {
444 | return inputData();
445 | }),
446 | _SetupCandidates: (function () {
447 | return [...arguments];
448 | }),
449 | }), [url]);
450 | });
451 |
452 | });
453 |
454 | context('_ParamCallbackDidFinish', function () {
455 |
456 | it('calls OLSKCacheWriteFile', async function () {
457 | const _ValueCandidatesCache = {
458 | [Math.random().toString()]: Math.random().toString(),
459 | };
460 |
461 | deepEqual(await __SetupDetail({
462 | _ValueCandidatesCache,
463 | OLSKCacheResultFetchRenew: (function (inputData) {
464 | return inputData._ParamCallbackDidFinish();
465 | }),
466 | OLSKCacheWriteFile: (function () {
467 | return [...arguments];
468 | }),
469 | }), [_ValueCandidatesCache, mod.DataCacheAggregateBasename(), require('path').join(__dirname, '__cached')]);
470 | });
471 |
472 | });
473 |
474 | });
475 |
476 | describe('SetupDetails', function test_SetupDetail() {
477 |
478 | const _SetupDetails = function (inputData = {}) {
479 | return Object.assign(Object.assign({}, mod), {
480 | DataBankProjects: (function () {
481 | return [];
482 | }),
483 | _SetupDetail: (function () {}),
484 | }, inputData).SetupDetails();
485 | };
486 |
487 | it('calls _SetupDetail', async function () {
488 | const item = {
489 | ZDAProjectURL: Math.random().toString(),
490 | };
491 | deepEqual(await _SetupDetails({
492 | _DataFoilBanks: {
493 | DataBankProjects: (function () {
494 | return [item];
495 | }),
496 | },
497 | _SetupDetail: (function () {
498 | return [...arguments].slice(0, 1);
499 | }),
500 | }), [[item.ZDAProjectURL]]);
501 | });
502 |
503 | });
504 |
505 | describe('_SetupDetailsIncoming', function test__SetupDetailsIncoming() {
506 |
507 | const __SetupDetailsIncoming = function (inputData = {}) {
508 | return Object.assign(Object.assign({}, mod), {
509 | DataBankProjects: (function () {
510 | return [];
511 | }),
512 | _SetupDetail: (function () {}),
513 | }, inputData)._SetupDetailsIncoming();
514 | };
515 |
516 | it('calls _SetupDetail', async function () {
517 | const item = {
518 | ZDAProjectURL: Math.random().toString(),
519 | };
520 | deepEqual(await __SetupDetailsIncoming({
521 | _DataFoilBanks: {
522 | DataBankProjects: (function () {
523 | return [item];
524 | }),
525 | },
526 | _SetupDetail: (function () {
527 | return [...arguments].slice(0, 1);
528 | }),
529 | }), [[item.ZDAProjectURL]]);
530 | });
531 |
532 | it('skips if _ValueCandidatesCache', async function () {
533 | const item = {
534 | ZDAProjectURL: Math.random().toString(),
535 | };
536 | deepEqual(await __SetupDetailsIncoming({
537 | _ValueCandidatesCache: {
538 | [item.ZDAProjectURL]: {},
539 | },
540 | _DataFoilBanks: {
541 | DataBankProjects: (function () {
542 | return [item];
543 | }),
544 | },
545 | _SetupDetail: (function () {
546 | return [...arguments].slice(0, 1);
547 | }),
548 | }), []);
549 | });
550 |
551 | });
552 |
--------------------------------------------------------------------------------
/os-app/task-b-details/controller.js:
--------------------------------------------------------------------------------
1 | const { JSDOM } = require('jsdom');
2 | const OLSKLink = require('OLSKLink');
3 | const OLSKCache = require('OLSKCache');
4 |
5 | const mod = {
6 |
7 | OLSKControllerTasks () {
8 | return [{
9 | OLSKTaskName: 'ZDADetailsStartFetch',
10 | OLSKTaskFireTimeInterval: 5,
11 | OLSKTaskShouldBePerformed () {
12 | return true;
13 | },
14 | OLSKTaskCallback: (function () {
15 | require('OLSKModule').OLSKModuleLifecycleSetup(mod);
16 | }),
17 | OLSKTaskFireLimit: 1,
18 | }, {
19 | OLSKTaskName: 'ZDADetailsCheckNewBankListings',
20 | OLSKTaskFireTimeInterval: 60 * 60 * 24,
21 | OLSKTaskShouldBePerformed () {
22 | return true;
23 | },
24 | OLSKTaskCallback: mod._SetupDetailsIncoming,
25 | }];
26 | },
27 |
28 | // VALUE
29 |
30 | _ValueCandidatesCache: {},
31 |
32 | ValueCandidatesCache () {
33 | return mod._ValueCandidatesCache;
34 | },
35 |
36 | // DATA
37 |
38 | _DataFoilOLSKCache: require('OLSKCache'),
39 | _DataFoilOLSKQueue: require('OLSKQueue'),
40 | _DataFoilOLSKDisk: require('OLSKDisk'),
41 | _DataFoilBanks: require('../task-a-banks/controller.js'),
42 |
43 | async _DataContentString (inputData) {
44 | if (inputData.match('nullboard.io')) {
45 | return '';
46 | }
47 |
48 | let response;
49 |
50 | try {
51 | response = await require('node-fetch')(inputData);
52 | } catch (e) {
53 | return '';
54 | }
55 |
56 | return mod._DataFoilOLSKDisk.OLSKDiskRead(OLSKCache.OLSKCachePath(__dirname, OLSKCache.OLSKCacheURLBasename(inputData))) || response.text();
57 | },
58 |
59 | DataCacheAggregateBasename() {
60 | return '_aggregate';
61 | },
62 |
63 | DataCacheImageAttributeCandidates () {
64 | return [
65 | 'apple-touch-icon',
66 | 'apple-touch-icon-precomposed',
67 | 'mask-icon',
68 | ];
69 | },
70 |
71 | _DataDOMPropertyCandidates (params) {
72 | if (typeof params !== 'object' || params === null) {
73 | throw new Error('ZDRErrorInputNotValid');
74 | }
75 |
76 | if (typeof params.ParamURL !== 'string') {
77 | throw new Error('ZDRErrorInputNotValid');
78 | }
79 |
80 | if (typeof params.ParamMetadata !== 'object' || params.ParamMetadata === null) {
81 | throw new Error('ZDRErrorInputNotValid');
82 | }
83 |
84 | if (typeof params.ParamManifest !== 'undefined') {
85 | if (typeof params.ParamManifest !== 'object' || params.ParamManifest === null) {
86 | throw new Error('ZDRErrorInputNotValid');
87 | }
88 | }
89 |
90 | return [
91 | ['ZDAProjectIconURL', (function(href) {
92 | if (!href) {
93 | return;
94 | }
95 |
96 | return !href ? null : OLSKLink.OLSKLinkRelativeURL(params.ParamURL, href);
97 | })((((params.ParamManifest || {}).icons || []).pop() || {}).src || mod.DataCacheImageAttributeCandidates().reduce(function (coll, item) {
98 | if (params.ParamMetadata[item]) {
99 | coll.push(params.ParamMetadata[item]);
100 | }
101 |
102 | return coll;
103 | }, []).shift())],
104 | ['_ZDAProjectIconURL', (function(href) {
105 | if (!href) {
106 | return;
107 | }
108 |
109 | return !href ? null : OLSKLink.OLSKLinkRelativeURL(params.ParamURL, href);
110 | })(params.ParamMetadata['og:image'])],
111 | ['ZDAProjectBlurb', params.ParamManifest?.description],
112 | ['_ZDAProjectBlurb', params.ParamMetadata.description],
113 | ['_ZDAProjectBlurb', params.ParamMetadata.title],
114 | ['ZDAProjectHasManifest', !!params.ParamManifest],
115 | ['ZDAProjectFunding', params.ParamMetadata._OLSKDOMMetadataFunding],
116 | ].filter(function ([key, value]) {
117 | return !!value;
118 | });
119 | },
120 |
121 | // SETUP
122 |
123 | SetupFetchQueue () {
124 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
125 |
126 | _mod._ValueFetchQueue = _mod._DataFoilOLSKQueue.OLSKQueueAPI();
127 | },
128 |
129 | SetupCacheObject () {
130 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
131 |
132 | Object.assign(mod, Object.assign(_mod, {
133 | _ValueCandidatesCache: _mod._DataFoilOLSKCache.OLSKCacheReadFile(mod.DataCacheAggregateBasename(), require('path').join(__dirname, '__cached')) || {},
134 | }));
135 | },
136 |
137 | async _SetupCandidates (inputData) {
138 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
139 |
140 | const ParamMetadata = require('OLSKDOM').OLSKDOMMetadata(_mod._DataFoilOLSKDisk.OLSKDiskWrite(OLSKCache.OLSKCachePath(__dirname, OLSKCache.OLSKCacheURLBasename(inputData)), await _mod._DataContentString(inputData)), {
141 | JSDOM: JSDOM.fragment,
142 | });
143 |
144 | return Object.fromEntries(_mod._DataDOMPropertyCandidates({
145 | ParamURL: inputData,
146 | ParamMetadata,
147 | ParamManifest: !ParamMetadata.manifest ? undefined : (function(body) {
148 | try {
149 | return JSON.parse(_mod._DataFoilOLSKDisk.OLSKDiskWrite(OLSKCache.OLSKCachePath(__dirname, OLSKCache.OLSKCacheURLBasename(OLSKLink.OLSKLinkRelativeURL(inputData, ParamMetadata.manifest))), body));
150 | } catch (error) {
151 | return;
152 | }
153 | })(await _mod._DataContentString(OLSKLink.OLSKLinkRelativeURL(inputData, ParamMetadata.manifest))),
154 | }));
155 | },
156 |
157 | _SetupDetail (inputData) {
158 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
159 |
160 | return _mod._DataFoilOLSKCache.OLSKCacheResultFetchRenew({
161 | ParamMap: _mod._ValueCandidatesCache,
162 | ParamKey: inputData,
163 | ParamCallback: (function () {
164 | return _mod._ValueFetchQueue.OLSKQueueAdd(function () {
165 | return _mod._SetupCandidates(inputData);
166 | });
167 | }),
168 | ParamInterval: 1000 * 60 * 60 * 24,
169 | _ParamCallbackDidFinish: (function () {
170 | return _mod._DataFoilOLSKCache.OLSKCacheWriteFile(_mod._ValueCandidatesCache, mod.DataCacheAggregateBasename(), require('path').join(__dirname, '__cached'));
171 | }),
172 | });
173 | },
174 |
175 | SetupDetails () {
176 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
177 |
178 | return _mod._DataFoilBanks.DataBankProjects().map(function (e) {
179 | return _mod._SetupDetail(e.ZDAProjectURL);
180 | })
181 | },
182 |
183 | _SetupDetailsIncoming () {
184 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
185 |
186 | return _mod._DataFoilBanks.DataBankProjects().filter(function (e) {
187 | return !_mod._ValueCandidatesCache[e.ZDAProjectURL];
188 | }).map(function (e) {
189 | return _mod._SetupDetail(e.ZDAProjectURL);
190 | })
191 | },
192 |
193 | };
194 |
195 | Object.assign(exports, mod);
196 |
--------------------------------------------------------------------------------
/os-app/task-c-images/controller-tests.js:
--------------------------------------------------------------------------------
1 | const { throws, rejects, deepEqual } = require('assert');
2 |
3 | const mod = require('./controller.js');
4 |
5 | const OLSKCache = require('OLSKCache');
6 |
7 | describe('DataCachePath', function test_DataCachePath() {
8 |
9 | it('returns string', function () {
10 | deepEqual(mod.DataCachePath(), require('path').join(__dirname, '__cached', 'ui-assets'));
11 | });
12 |
13 | it('throws if not string', function () {
14 | throws(function () {
15 | mod.DataCachePath(null);
16 | }, /ZDAErrorInputNotValid/);
17 | });
18 |
19 | it('joins inputData', function () {
20 | const item = Math.random().toString();
21 | deepEqual(mod.DataCachePath(item), require('path').join(__dirname, '__cached', 'ui-assets', item));
22 | });
23 |
24 | });
25 |
26 | describe('DataCacheLocalPath', function test_DataCacheLocalPath() {
27 |
28 | const _DataCacheLocalPath = function (inputData) {
29 | return Object.assign(Object.assign({}, mod), {
30 | _DataFoilFS: Object.assign({
31 | existsSync: (function () {}),
32 | }, inputData),
33 | }, inputData).DataCacheLocalPath(inputData.url || uLink());
34 | };
35 |
36 | it('calls existsSync', function () {
37 | const item = [];
38 |
39 | const url = uLink();
40 |
41 | _DataCacheLocalPath({
42 | url,
43 | existsSync: (function () {
44 | item.push(...arguments);
45 | }),
46 | });
47 |
48 | deepEqual(item, [mod.DataCachePath(OLSKCache.OLSKCacheURLFilename(url))]);
49 | });
50 |
51 | it('returns local URL if existsSync', function () {
52 | const url = uLink();
53 |
54 | deepEqual(_DataCacheLocalPath({
55 | url,
56 | existsSync: (function () {
57 | return true;
58 | }),
59 | }), mod.DataCachePath(OLSKCache.OLSKCacheURLFilename(url)).replace(require('path').join(__dirname, '../'), '/'));
60 | });
61 |
62 | it('returns null', function () {
63 | deepEqual(_DataCacheLocalPath({
64 | existsSync: (function () {
65 | return false;
66 | }),
67 | }), null);
68 | });
69 |
70 | });
71 |
72 | describe('SetupFetchQueue', function test_SetupFetchQueue() {
73 |
74 | const _SetupFetchQueue = function (inputData) {
75 | const _mod = Object.assign(Object.assign({}, mod), {
76 | _DataFoilOLSKQueue: inputData,
77 | }, inputData);
78 | return _mod.SetupFetchQueue() || _mod;
79 | };
80 |
81 | it('calls OLSKQueueAPI', function () {
82 | const item = Math.random().toString();
83 | deepEqual(_SetupFetchQueue({
84 | OLSKQueueAPI: (function () {
85 | return [...arguments].concat(item);
86 | }),
87 | })._ValueFetchQueue, [item]);
88 | });
89 |
90 | it('sets _ValueFetchQueue', function () {
91 | const item = Math.random().toString();
92 |
93 | deepEqual(_SetupFetchQueue({
94 | OLSKQueueAPI: (function () {
95 | return item;
96 | }),
97 | })._ValueFetchQueue, item);
98 | });
99 |
100 | });
101 |
102 | describe('_SetupImage', function test__SetupImage() {
103 |
104 | const __SetupImage = function (inputData = {}) {
105 | return Object.assign(Object.assign({}, mod), {
106 | _ValueFetchQueue: Object.assign({}, inputData),
107 | _DataImagePipe: (function () {}),
108 | }, inputData)._SetupImage(inputData.url);
109 | };
110 |
111 | it('calls OLSKQueueAdd', async function () {
112 | const url = uLink();
113 |
114 | deepEqual(await __SetupImage({
115 | url,
116 | OLSKQueueAdd: (function () {
117 | return [...arguments].map(function (e) {
118 | return typeof e;
119 | });
120 | }),
121 | }), ['function']);
122 | });
123 |
124 | it('calls _DataImagePipe', async function () {
125 | const url = uLink();
126 |
127 | deepEqual(await __SetupImage({
128 | url,
129 | OLSKQueueAdd: (function (inputData) {
130 | return inputData();
131 | }),
132 | _DataImagePipe: (function () {
133 | return [...arguments];
134 | }),
135 | }), [url, mod.DataCachePath(OLSKCache.OLSKCacheURLFilename(url))]);
136 | });
137 |
138 | });
139 |
140 | describe('SetupImages', function test_SetupImages() {
141 |
142 | const _SetupImages = function (inputData = {}) {
143 | return Object.assign(Object.assign({}, mod), {
144 | _DataFoilProjects: Object.assign({
145 | DataProjects: (function () {
146 | return [];
147 | }),
148 | }, inputData),
149 | _DataFoilBanks: Object.assign({
150 | DataBankProtocols: (function () {
151 | return [];
152 | }),
153 | }, inputData),
154 | _SetupImage: (function () {}),
155 | }, inputData).SetupImages();
156 | };
157 |
158 | it('calls _SetupImage', async function () {
159 | const ZDAProjectIconURL = Math.random().toString();
160 |
161 | deepEqual(await _SetupImages({
162 | DataProjects: (function () {
163 | return [{
164 | ZDAProjectIconURL,
165 | }];
166 | }),
167 | _SetupImage: (function () {
168 | return [...arguments];
169 | }),
170 | }), [[ZDAProjectIconURL]]);
171 | });
172 |
173 | it('ignores if no ZDAProjectIconURL', async function () {
174 | deepEqual(await _SetupImages({
175 | DataProjects: (function () {
176 | return [{}];
177 | }),
178 | }), []);
179 | });
180 |
181 | it('ignores if already local', async function () {
182 | const ZDAProjectIconURL = Math.random().toString();
183 | deepEqual(await _SetupImages({
184 | DataProjects: (function () {
185 | return [{
186 | ZDAProjectIconURL: Math.random().toString(),
187 | _ZDAProjectIconURLCachedPath: Math.random().toString(),
188 | }];
189 | }),
190 | _DataImagePipe: (function () {
191 | return [...arguments];
192 | }),
193 | }), []);
194 | });
195 |
196 | context('DataBankProtocols', function () {
197 |
198 | it('calls _SetupImage', async function () {
199 | const ZDAProtocolIconURL = Math.random().toString();
200 |
201 | deepEqual(await _SetupImages({
202 | DataBankProtocols: (function () {
203 | return [{
204 | ZDAProtocolIconURL,
205 | }];
206 | }),
207 | _SetupImage: (function () {
208 | return [...arguments];
209 | }),
210 | }), [[ZDAProtocolIconURL]]);
211 | });
212 |
213 | it('ignores if no ZDAProtocolIconURL', async function () {
214 | deepEqual(await _SetupImages({
215 | DataBankProtocols: (function () {
216 | return [{}];
217 | }),
218 | }), []);
219 | });
220 |
221 | it('ignores if already local', async function () {
222 | const ZDAProtocolIconURL = Math.random().toString();
223 | deepEqual(await _SetupImages({
224 | DataBankProtocols: (function () {
225 | return [{
226 | ZDAProtocolIconURL: Math.random().toString(),
227 | _ZDAProtocolIconURLCachedPath: Math.random().toString(),
228 | }];
229 | }),
230 | _DataImagePipe: (function () {
231 | return [...arguments];
232 | }),
233 | }), []);
234 | });
235 |
236 | });
237 |
238 | });
239 |
--------------------------------------------------------------------------------
/os-app/task-c-images/controller.js:
--------------------------------------------------------------------------------
1 | const OLSKCache = require('OLSKCache');
2 |
3 | const mod = {
4 |
5 | OLSKControllerTasks () {
6 | return [{
7 | OLSKTaskName: 'ZDAImagesStartFetch',
8 | OLSKTaskFireTimeInterval: 10,
9 | OLSKTaskShouldBePerformed () {
10 | return true;
11 | },
12 | OLSKTaskCallback: (function () {
13 | require('OLSKModule').OLSKModuleLifecycleSetup(mod);
14 | }),
15 | OLSKTaskFireLimit: 1,
16 | }, {
17 | OLSKTaskName: 'ZDAImagesFetchIncoming',
18 | OLSKTaskFireTimeInterval: 60 * 60,
19 | OLSKTaskShouldBePerformed () {
20 | return true;
21 | },
22 | OLSKTaskCallback: mod.SetupImages,
23 | }];
24 | },
25 |
26 | // DATA
27 |
28 | _DataFoilOLSKQueue: require('OLSKQueue'),
29 | _DataFoilFS: require('fs'),
30 | _DataFoilProjects: require('../api-projects/controller.js'),
31 | _DataFoilBanks: require('../task-a-banks/controller.js'),
32 |
33 | async _DataImagePipe (url, file) {
34 | const {createWriteStream} = require('fs');
35 | const {pipeline} = require('stream');
36 | const {promisify} = require('util');
37 | const fetch = require('node-fetch');
38 |
39 | const streamPipeline = promisify(pipeline);
40 |
41 | Object.entries({
42 | 'https://laverna.cc/apple-touch-icon.png': 'https://laverna.cc/app/images/icon/icon-152x152.png',
43 | 'https://noeldemartin.github.io/media-kraken/img/icons/android-chrome-maskable-512x512.png': 'https://noeldemartin.github.io/media-kraken/img/icons/android-chrome-512x512.png',
44 | 'https://thewebalyst.solidcommunity.net/plume/img/favicon.png': 'https://thewebalyst.solidcommunity.net/plume/favicon.png',
45 | 'https://madelinemiller.dev/apps/emojify/icons/icon-512x512.png': 'https://madelinemiller.dev/static/ff435ace25032a4f5a8b09bb98a28dbc/emojify-icon.png',
46 | 'https://jeremyckahn.github.io/logoMaskable.png': 'https://jeremyckahn.github.io/farmhand/app-icons/ios-appicon-180-180.png',
47 | 'https://find.internet4000.com/public/favicon/android-chrome-512x512.png': 'https://find.internet4000.com/public/favicons/apple-touch-icon.png',
48 | 'https://hihayk.github.io/logo512.png': 'https://hihayk.github.io/shaper/logo192.png',
49 | 'https://petrolette.space/public/images/favicons/android-chrome-256x256.png': 'https://petrolette.space/static/images/favicons/apple-touch-icon.png',
50 | }).forEach(function ([source, destination]) {
51 | if (url.match(source)) {
52 | url = destination;
53 | }
54 | });
55 |
56 | const response = await fetch(url);
57 |
58 | if (!response.ok) {
59 | console.log(`unexpected response from ${url}\n${response.statusText}`);
60 | return;
61 | }
62 |
63 | require('OLSKDisk').OLSKDiskCreateFolder(require('path').dirname(file));
64 |
65 | await streamPipeline(response.body, createWriteStream(file));
66 | },
67 |
68 | DataCachePath (inputData = '') {
69 | if (typeof inputData !== 'string') {
70 | throw new Error('ZDAErrorInputNotValid');
71 | }
72 |
73 | return require('path').join(__dirname, '__cached', 'ui-assets', inputData);
74 | },
75 |
76 | DataCacheLocalPath (inputData) {
77 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
78 |
79 | const localURL = mod.DataCachePath(OLSKCache.OLSKCacheURLFilename(inputData));
80 | return _mod._DataFoilFS.existsSync(localURL) ? localURL.replace(require('path').join(__dirname, '../'), '/') : null;
81 | },
82 |
83 | // SETUP
84 |
85 | SetupFetchQueue () {
86 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
87 |
88 | _mod._ValueFetchQueue = _mod._DataFoilOLSKQueue.OLSKQueueAPI();
89 | },
90 |
91 | _SetupImage (inputData) {
92 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
93 |
94 | return _mod._ValueFetchQueue.OLSKQueueAdd(function () {
95 | return mod.DataCacheLocalPath(inputData) || _mod._DataImagePipe(inputData, mod.DataCachePath(OLSKCache.OLSKCacheURLFilename(inputData)));
96 | });
97 | },
98 |
99 | SetupImages () {
100 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
101 |
102 | return _mod._DataFoilProjects.DataProjects().concat(_mod._DataFoilBanks.DataBankProtocols()).reduce(function (coll, item) {
103 | return coll.concat(item.ZDAProjectIconURL && !item._ZDAProjectIconURLCachedPath ? item.ZDAProjectIconURL : (item.ZDAProtocolIconURL && !item._ZDAProtocolIconURLCachedPath ? item.ZDAProtocolIconURL : []));
104 | }, []).map(function (e) {
105 | return _mod._SetupImage(e);
106 | });
107 | },
108 |
109 | };
110 |
111 | Object.assign(exports, mod);
112 |
--------------------------------------------------------------------------------
/os-app/task-d-events/controller-tests.js:
--------------------------------------------------------------------------------
1 | const { throws, rejects, deepEqual } = require('assert');
2 |
3 | const mod = require('./controller.js');
4 |
5 | const OLSKCache = require('OLSKCache');
6 |
7 | describe('ZDAEventURLs', function test_ZDAEventURLs() {
8 |
9 | it('returns array', function () {
10 | deepEqual(mod.ZDAEventURLs(), process.env.ZDA_TASK_EVENTS_URLS.split(','));
11 | });
12 |
13 | });
14 |
15 | describe('ZDAEventURLRemoteStorage', function test_ZDAEventURLRemoteStorage() {
16 |
17 | it('returns string', function () {
18 | deepEqual(mod.ZDAEventURLRemoteStorage(), mod.ZDAEventURLs().filter(function (e) {
19 | return e.match(/RemoteStorage/i);
20 | }).shift());
21 | });
22 |
23 | });
24 |
25 | describe('ZDAEventURLFission', function test_ZDAEventURLFission() {
26 |
27 | it('returns string', function () {
28 | deepEqual(mod.ZDAEventURLFission(), mod.ZDAEventURLs().filter(function (e) {
29 | return e.match(/fission/i);
30 | }).shift());
31 | });
32 |
33 | });
34 |
35 | describe('ZDAEventURLSolidProject', function test_ZDAEventURLSolidProject() {
36 |
37 | it('returns string', function () {
38 | deepEqual(mod.ZDAEventURLSolidProject(), mod.ZDAEventURLs().filter(function (e) {
39 | return e.match(/Solid/i);
40 | }).shift());
41 | });
42 |
43 | });
44 |
45 | describe('_DataEventObjects', function test__DataEventObjects() {
46 |
47 | it('throws if param1 not in ZDAEventURLs', function () {
48 | throws(function () {
49 | mod._DataEventObjects(Math.random().toString(), Math.random().toString());
50 | }, /ZDAErrorInputNotValid/);
51 | });
52 |
53 | it('throws if param2 not string', function () {
54 | throws(function () {
55 | mod._DataEventObjects(uRandomElement(mod.ZDAEventURLs()), null);
56 | }, /ZDAErrorInputNotValid/);
57 | });
58 |
59 | it('returns array', function () {
60 | deepEqual(mod._DataEventObjects(uRandomElement(mod.ZDAEventURLs()), ''), []);
61 | });
62 |
63 | context('RemoteStorage', function test_RemoteStorage () {
64 |
65 | const uEvent = function (inputData = {}) {
66 | const item = Object.assign({
67 | ZDAEventURL: Math.random().toString(),
68 | ZDAEventName: Math.random().toString(),
69 | ZDAEventStart: new Date(),
70 | }, inputData);
71 |
72 | return `
73 | - ${ item.ZDAEventName }I’ve been thinking about updating the website design, moving wiki content to forum, doing events and a newsletter, grant opportunities… Be welcome to join @raucao and I in the call and share your thoughts.
75 |
76 |
1 post - 1 participant
77 | Read full topic
78 | ]]>https://community.remotestorage.io/t/community-call-redesigning-the-remotestorage-homepage-other-stuff/705Community call: Redesigning the remoteStorage homepage + other stuff `;
79 | };
80 |
81 | it('parses data', function () {
82 | const ZDAEventURL = Math.random().toString();
83 | const ZDAEventName = Math.random().toString();
84 | const ZDAEventStart = new Date();
85 |
86 | deepEqual(mod._DataEventObjects(mod.ZDAEventURLRemoteStorage(), uEvent({
87 | ZDAEventURL,
88 | ZDAEventName,
89 | ZDAEventStart,
90 | })), [{
91 | ZDAEventURL,
92 | ZDAEventName,
93 | ZDAEventStart,
94 | }]);
95 | });
96 |
97 | });
98 |
99 | context('Fission', function test_Fission () {
100 |
101 | const uEvent = function (inputData = {}) {
102 | const item = Object.assign({
103 | ZDAEventURL: Math.random().toString(),
104 | ZDAEventName: Math.random().toString(),
105 | ZDAEventStart: new Date(),
106 | }, inputData);
107 |
108 | return ``;
109 | };
110 |
111 | it('parses data', function () {
112 | const ZDAEventURL = Math.random().toString();
113 | const ZDAEventName = Math.random().toString();
114 | const ZDAEventStart = new Date();
115 |
116 | deepEqual(mod._DataEventObjects(mod.ZDAEventURLFission(), uEvent({
117 | ZDAEventURL,
118 | ZDAEventName,
119 | ZDAEventStart,
120 | })), [{
121 | ZDAEventURL,
122 | ZDAEventName,
123 | ZDAEventStart,
124 | }]);
125 | });
126 |
127 | });
128 |
129 | context('SolidProject', function test_SolidProject () {
130 |
131 | const uEvent = function (inputData = {}) {
132 | const item = Object.assign({
133 | ZDAEventURL: Math.random().toString(),
134 | ZDAEventName: Math.random().toString(),
135 | ZDAEventStart: new Date(),
136 | }, inputData);
137 |
138 | // return `2021 Events
${ item.ZDAEventStart.toJSON().slice(0, 10) } | ${ item.ZDAEventName } | Solid Team | Solid over the Interplanetary File System Fabrizio Parrillo (U. Basel, Switzerland), Christian F Tschudin (U. Basel, Switzerland) |
2021-07-01 | Solid World | Solid Team | Solid over the Interplanetary File System Fabrizio Parrillo (U. Basel, Switzerland), Christian F Tschudin (U. Basel, Switzerland) |
`;
139 | return ``;
140 | };
141 |
142 | it('parses data', function () {
143 | const ZDAEventURL = Math.random().toString();
144 | const ZDAEventName = Math.random().toString();
145 | const ZDAEventStart = new Date();
146 |
147 | deepEqual(mod._DataEventObjects(mod.ZDAEventURLSolidProject(), uEvent({
148 | ZDAEventURL,
149 | ZDAEventName,
150 | ZDAEventStart,
151 | })), [{
152 | ZDAEventURL,
153 | ZDAEventName,
154 | ZDAEventStart,
155 | }]);
156 | });
157 |
158 | });
159 |
160 | });
161 |
162 | describe('DataEvents', function test_DataEvents() {
163 |
164 | const _DataEvents = function (inputData = {}) {
165 | return Object.assign(Object.assign({}, mod), {
166 | _OLSKCacheResultMap: {},
167 | _DataEventObjects: (function () {
168 | return [];
169 | }),
170 | }, inputData).DataEvents();
171 | };
172 |
173 | it('calls _DataEventObjects', function () {
174 | const item = [];
175 |
176 | const _OLSKCacheResultMap = mod.ZDAEventURLs().reduce(function (coll, item) {
177 | return Object.assign(coll, {
178 | [item]: Math.random().toString(),
179 | });
180 | }, {});
181 |
182 | _DataEvents({
183 | _OLSKCacheResultMap,
184 | _DataEventObjects: (function () {
185 | item.push([...arguments]);
186 |
187 | return [];
188 | }),
189 | });
190 |
191 | deepEqual(item, mod.ZDAEventURLs().map(function (e) {
192 | return [e, _OLSKCacheResultMap[e]];
193 | }));
194 | });
195 |
196 | it('trims properties', function () {
197 | const item = Math.random().toString();
198 | const ZDAEventStart = new Date(Date.now() + 1000);
199 |
200 | deepEqual(_DataEvents({
201 | _DataEventObjects: (function () {
202 | return [{
203 | ZDAEventURL: arguments[0],
204 | ZDAEventStart,
205 | [item]: ' ' + item + ' ',
206 | }];
207 | }),
208 | }), mod.ZDAEventURLs().reduce(function (coll, ZDAEventURL) {
209 | return coll.concat({
210 | ZDAEventURL,
211 | ZDAEventStart,
212 | [item]: item,
213 | });
214 | }, []));
215 | });
216 |
217 | it('filters if past', function () {
218 | deepEqual(_DataEvents({
219 | _DataEventObjects: (function () {
220 | return [{
221 | ZDAEventURL: arguments[0],
222 | ZDAEventStart: new Date(Date.now() - 1000),
223 | }];
224 | }),
225 | }), []);
226 | });
227 |
228 | it('sorts by ZDAEventStart', function () {
229 | const item = Date.now() + 1000;
230 | deepEqual(_DataEvents({
231 | _DataEventObjects: (function () {
232 | return [{
233 | ZDAEventURL: arguments[0],
234 | ZDAEventStart: new Date(item + mod.ZDAEventURLs().length - mod.ZDAEventURLs().indexOf(arguments[0])),
235 | }];
236 | }),
237 | }), mod.ZDAEventURLs().reverse().map(function (ZDAEventURL, i) {
238 | return {
239 | ZDAEventURL,
240 | ZDAEventStart: new Date(item + 1 + i),
241 | };
242 | }, []));
243 | });
244 |
245 | });
246 |
247 | describe('_SetupEvent', function test__SetupEvent() {
248 |
249 | const __SetupEvent = function (inputData) {
250 | return Object.assign(Object.assign({}, mod), {
251 | _DataContentJSON: (function () {}),
252 |
253 | _DataFoilOLSKCache: Object.assign({
254 | OLSKCacheQueuedFetch: (function () {}),
255 | }, inputData),
256 |
257 | _DataFoilOLSKDisk: Object.assign({
258 | OLSKDiskWrite: (function () {}),
259 | }, inputData),
260 | }, inputData)._SetupEvent(inputData.ParamKey || Math.random().toString());
261 | };
262 |
263 | it('calls OLSKCacheQueuedFetch', function () {
264 | const ParamKey = Math.random().toString();
265 | const OLSKDisk = {};
266 | const item = (uCapture(function (OLSKCacheQueuedFetch) {
267 | __SetupEvent({
268 | ParamKey,
269 |
270 | OLSKCacheQueuedFetch,
271 | _DataFoilOLSKDisk: OLSKDisk,
272 | });
273 | })).pop();
274 |
275 | deepEqual(item, {
276 | ParamMod: mod,
277 | ParamKey,
278 | ParamCallback: item.ParamCallback,
279 | ParamInterval: 1000 * 60 * 60 * 24,
280 | ParamFileURLs: mod.ZDAEventURLs(),
281 | ParamFileDirectory: __dirname,
282 | OLSKQueue: require('OLSKQueue'),
283 | OLSKDisk,
284 | });
285 | });
286 |
287 | context('ParamCallback', function () {
288 |
289 | it('calls _DataContentString', async function () {
290 | const ParamKey = Math.random().toString();
291 | deepEqual(await __SetupEvent({
292 | ParamKey,
293 | OLSKCacheQueuedFetch: (function (inputData) {
294 | return inputData.ParamCallback();
295 | }),
296 | _DataContentString: (function () {
297 | return [...arguments];
298 | }),
299 | }), [ParamKey]);
300 | });
301 |
302 | });
303 |
304 | });
305 |
306 | describe('SetupEvents', function test_SetupEvents() {
307 |
308 | const _SetupEvents = function (inputData = {}) {
309 | return Object.assign(Object.assign({}, mod), {
310 | _SetupEvent: (function () {}),
311 | }, inputData).SetupEvents();
312 | };
313 |
314 | it('calls _SetupEvent', async function () {
315 | deepEqual(await _SetupEvents({
316 | _SetupEvent: (function (e) {
317 | return e;
318 | }),
319 | }), mod.ZDAEventURLs());
320 | });
321 |
322 | });
323 |
--------------------------------------------------------------------------------
/os-app/task-d-events/controller.js:
--------------------------------------------------------------------------------
1 | const cheerio = require('cheerio');
2 | const OLSKCache = require('OLSKCache');
3 |
4 | const uAscending = function (a, b) {
5 | return (a < b) ? -1 : ((a > b) ? 1 : 0);
6 | };
7 |
8 | const mod = {
9 |
10 | OLSKControllerTasks () {
11 | return [{
12 | OLSKTaskName: 'ZDAEventsStartFetch',
13 | OLSKTaskFireTimeInterval: 1,
14 | OLSKTaskShouldBePerformed () {
15 | return true;
16 | },
17 | OLSKTaskCallback: (function () {
18 | require('OLSKModule').OLSKModuleLifecycleSetup(mod);
19 | }),
20 | OLSKTaskFireLimit: 1,
21 | }];
22 | },
23 |
24 | OLSKControllerSharedLocals () {
25 | return {
26 | ZDAEvents () {
27 | return mod.DataEvents();
28 | },
29 | };
30 | },
31 |
32 | // DATA
33 |
34 | _DataFoilOLSKCache: OLSKCache,
35 | _DataFoilOLSKQueue: require('OLSKQueue'),
36 | _DataFoilOLSKDisk: require('OLSKDisk'),
37 |
38 | ZDAEventURLs() {
39 | return process.env.ZDA_TASK_EVENTS_URLS.split(',');
40 | },
41 |
42 | ZDAEventURLRemoteStorage () {
43 | return mod.ZDAEventURLs().filter(function (e) {
44 | return e.match(/RemoteStorage/i);
45 | }).shift();
46 | },
47 |
48 | ZDAEventURLFission () {
49 | return mod.ZDAEventURLs().filter(function (e) {
50 | return e.match(/fission/i);
51 | }).shift();
52 | },
53 |
54 | ZDAEventURLSolidProject () {
55 | return mod.ZDAEventURLs().filter(function (e) {
56 | return e.match(/Solid/i);
57 | }).shift();
58 | },
59 |
60 | async _DataContentString (inputData) {
61 | return (await require('node-fetch')(inputData)).text();
62 | },
63 |
64 | _DataEventObjects (param1, param2) {
65 | if (!mod.ZDAEventURLs().includes(param1)) {
66 | throw new Error('ZDAErrorInputNotValid');
67 | }
68 |
69 | if (typeof param2 !== 'string') {
70 | throw new Error('ZDAErrorInputNotValid');
71 | }
72 |
73 | return Array.from(mod.ZDAEventURLs().reduce(function (coll, item) {
74 | return Object.assign(coll, {
75 | [item]: {
76 | [mod.ZDAEventURLRemoteStorage()]: function () {
77 | return cheerio('channel', param2).first().find('item').filter(function () {
78 | return cheerio('description', this).html().match('discourse-post-event');
79 | }).map(function () {
80 | return {
81 | ZDAEventURL: cheerio('source', this).attr('url').split('.rss').shift(),
82 | ZDAEventName: cheerio('title', this).text(),
83 | ZDAEventStart: new Date(cheerio('description', this).html().match(/data-start="(.*)/)[0].split('"')[1]),
84 | };
85 | });
86 | },
87 | [mod.ZDAEventURLFission()]: function () {
88 | return (param2 ? JSON.parse(param2.split('').shift()).props.pageProps.initialData.data.featured_items : []).map(function (e) {
89 | return {
90 | ZDAEventURL: e.event.url,
91 | ZDAEventName: e.event.name,
92 | ZDAEventStart: new Date(e.event.start_at),
93 | };
94 | });
95 | },
96 | [mod.ZDAEventURLSolidProject()]: function () {
97 | // return cheerio('article.content table', param2).first().find('tr').map(function () {
98 | // return {
99 | // ZDAEventURL: cheerio(':nth-child(2) a', this).attr('href') || '',
100 | // ZDAEventName: cheerio(':nth-child(2) a', this).text(),
101 | // ZDAEventStart: require('luxon').DateTime.fromISO(cheerio('td:nth-child(1)', this).text() + 'T16:00:00', {
102 | // setZone: true,
103 | // zone: 'Europe/Rome',
104 | // }).toJSDate(),
105 | // };
106 | // });
107 | return (param2 ? JSON.parse(param2.split('').shift()) : []).map(function (e) {
108 | return {
109 | ZDAEventURL: e.url,
110 | ZDAEventName: e.name,
111 | // ZDAEventStart: require('luxon').DateTime.fromISO(ZDAEventStart.toJSON().slice(0, 10) + 'T16:00:00', {
112 | // setZone: true,
113 | // zone: 'Europe/Rome',
114 | // }).toJSDate(),
115 | ZDAEventStart: new Date(e.startDate),
116 | };
117 | });
118 | },
119 | }[item],
120 | });
121 | }, {})[param1]()).map(function (e) {
122 | return Object.fromEntries(Object.entries(e).map(function (e) {
123 | return e.map(function (e) {
124 | if (typeof e !== 'string') {
125 | return e;
126 | }
127 |
128 | return e.trim();
129 | });
130 | }));
131 | });
132 | },
133 |
134 | DataEvents () {
135 | if (process.env.OLSK_FLAG_CI) {
136 | return [];
137 | }
138 |
139 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
140 |
141 | return _mod.ZDAEventURLs().reduce(function (coll, item) {
142 | return coll.concat(_mod._DataEventObjects(item, _mod._OLSKCacheResultMap[item] || '').map(require('OLSKObject').OLSKObjectTrim));
143 | }, []).filter(function (e) {
144 | return e.ZDAEventStart > new Date();
145 | }).sort(function (a, b) {
146 | return uAscending(a.ZDAEventStart, b.ZDAEventStart);
147 | });
148 | },
149 |
150 | // SETUP
151 |
152 | _SetupEvent (inputData) {
153 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
154 |
155 | return _mod._DataFoilOLSKCache.OLSKCacheQueuedFetch({
156 | ParamMod: mod,
157 | ParamKey: inputData,
158 | ParamCallback: (function () {
159 | return _mod._DataContentString(inputData);
160 | }),
161 | ParamInterval: 1000 * 60 * 60 * 24,
162 | ParamFileURLs: mod.ZDAEventURLs(),
163 | ParamFileDirectory: __dirname,
164 | OLSKQueue: _mod._DataFoilOLSKQueue,
165 | OLSKDisk: _mod._DataFoilOLSKDisk,
166 | });
167 | },
168 |
169 | SetupEvents () {
170 | const _mod = process.env.npm_lifecycle_script === 'olsk-spec' ? this : mod;
171 |
172 | return Promise.all(mod.ZDAEventURLs().map(_mod._SetupEvent));
173 | },
174 |
175 | };
176 |
177 | Object.assign(exports, mod);
178 |
--------------------------------------------------------------------------------
/os-app/tech-robots/controller.js:
--------------------------------------------------------------------------------
1 | exports.OLSKControllerRoutes = function() {
2 | return [{
3 | OLSKRoutePath: '/robots.txt',
4 | OLSKRouteMethod: 'get',
5 | OLSKRouteSignature: 'ZDARobotsRoute',
6 | OLSKRouteFunction (req, res, next) {
7 | return res.send(require('OLSKRobots').OLSKRobotsTXT([
8 | 'ZDAVitrineRoute',
9 | 'ZDAGlanceRoute',
10 | 'ZDAProjectsJSONRoute',
11 | ].reduce(function (coll, item) {
12 | return coll.concat(res.locals.OLSKCanonical(item)).concat((res.locals.OLSKRouteObjectFor(item).OLSKRouteLanguageCodes || []).map(function (e) {
13 | return res.locals.OLSKCanonicalLocalized(item, {
14 | OLSKRoutingLanguage: e,
15 | });
16 | }));
17 | }, []).concat('/application_icon_*')));
18 | },
19 | }];
20 | };
21 |
--------------------------------------------------------------------------------
/os-app/tech-robots/ui-test-_misc.js:
--------------------------------------------------------------------------------
1 | const kDefaultRoute = require('./controller.js').OLSKControllerRoutes().shift();
2 |
3 | describe('ZDARobots_Misc', function () {
4 |
5 | it('sends text', async function () {
6 | return browser.assert.deepEqual(await (await browser.fetch('http://localhost:' + process.env.PORT + kDefaultRoute.OLSKRoutePath)).text(), require('OLSKRobots').OLSKRobotsTXT([
7 | require('../open-vitrine/controller.js').OLSKControllerRoutes().shift(),
8 | require('../open-glance/controller.js').OLSKControllerRoutes().shift(),
9 | require('../api-projects/controller.js').OLSKControllerRoutes().shift(),
10 | ].reduce(function (coll, item) {
11 | return coll.concat(OLSKTestingCanonical(item)).concat((item.OLSKRouteLanguageCodes || []).map(function (e) {
12 | return OLSKTestingCanonical(item, {
13 | OLSKRoutingLanguage: e,
14 | });
15 | }));
16 | }, []).concat('/application_icon_*')));
17 | });
18 |
19 | });
20 |
--------------------------------------------------------------------------------
/package-postinstall.js:
--------------------------------------------------------------------------------
1 | (function OLSKPostinstallHotfix() {
2 | Object.entries(require('OLSKHotfix').OLSKHotfixPatches(process.env.NODE_ENV)).forEach(function ([path, patches]) {
3 | if (!require('fs').existsSync(path)) {
4 | return;
5 | }
6 |
7 | Object.entries(patches).forEach(function ([search, replace]) {
8 | require('fs').writeFileSync(path, require('OLSKString').OLSKStringPatch(
9 | require('fs').readFileSync(path, 'utf8'), search, replace));
10 | });
11 | });
12 | })();
13 |
14 | (function OLSKPostinstallExternalAssets() {
15 | require('./node_modules/OLSKExpress/modules/OLSKAssets/main.js').OLSKAssetsCopyAssetsFromTo([
16 | 'normalize.css',
17 | 'OLSKDecor',
18 | 'OLSKRootLink',
19 | 'OLSKUIAssets',
20 | 'ROCORootLink',
21 | 'list.js',
22 | ], require('path').join(__dirname, 'node_modules'), require('path').join(__dirname, 'os-app/_shared/__external'));
23 | })();
24 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "scripts": {
3 | "postinstall": "olsk-bundle tidy && node ./package-postinstall.js",
4 | "setup": "npm install --no-save && olsk-bundle",
5 | "start": "olsk-express",
6 | "test": "olsk-spec"
7 | },
8 | "dependencies": {
9 | "OLSKPithVitrine": "olsk/OLSKPithVitrine",
10 | "OLSKRobots": "olsk/OLSKRobots",
11 | "OLSKQueue": "olsk/OLSKQueue",
12 | "OLSKCache": "olsk/OLSKCache",
13 | "OLSKDisk": "olsk/OLSKDisk",
14 | "OLSKDOM": "olsk/OLSKDOM",
15 | "OLSKLink": "olsk/OLSKLink",
16 | "OLSKObject": "olsk/OLSKObject",
17 | "OLSKModule": "olsk/OLSKModule",
18 | "OLSKRootLink": "olsk/OLSKRootLink",
19 | "SWARLink": "0dataapp/SWARLink",
20 | "node-fetch": "2.x",
21 | "cheerio": "0.x",
22 | "list.js": "latest",
23 | "luxon": "latest"
24 | },
25 | "devDependencies": {
26 | "OLSKPithToolchain": "olsk/OLSKPithToolchain",
27 | "jsdom": "16.x"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------