15814: Catch error that otherwise goes unhandled
[arvados.git] / services / workbench2 / src / models / vocabulary.test.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as Vocabulary from './vocabulary';
6
7 describe('Vocabulary', () => {
8     let vocabulary: Vocabulary.Vocabulary;
9
10     beforeEach(() => {
11         vocabulary = {
12             strict_tags: false,
13             tags: {
14                 IDKEYCOMMENT: {
15                     labels: []
16                 },
17                 IDKEYANIMALS: {
18                     strict: false,
19                     labels: [
20                         {label: "Animal" },
21                         {label: "Creature"},
22                         {label: "Beast"},
23                     ],
24                     values: {
25                         IDVALANIMALS1: {
26                             labels: [
27                                 {label: "Human"},
28                                 {label: "Homo sapiens"}
29                             ]
30                         },
31                         IDVALANIMALS2: {
32                             labels: [
33                                 {label: "Dog"},
34                                 {label: "Canis lupus familiaris"}
35                             ]
36                         },
37                     }
38                 },
39                 IDKEYSIZES: {
40                     labels: [{label: "Sizes"}],
41                     values: {
42                         IDVALSIZES1: {
43                             labels: [{label: "Small"}, {label: "S"}, {label: "Little"}]
44                         },
45                         IDVALSIZES2: {
46                             labels: [{label: "Medium"}, {label: "M"}]
47                         },
48                         IDVALSIZES3: {
49                             labels: [{label: "Large"}, {label: "L"}]
50                         },
51                         IDVALSIZES4: {
52                             labels: []
53                         }
54                     }
55                 },
56                 automation: {
57                     strict: true,
58                     labels: [],
59                     values: {
60                         upload: { labels: [] },
61                         results: { labels: [] },
62                     }
63                 }
64             }
65         }
66     });
67
68     it('returns the list of tag keys', () => {
69         const tagKeys = Vocabulary.getTags(vocabulary);
70         // Alphabetically ordered by label
71         expect(tagKeys).toEqual([
72             {id: "IDKEYANIMALS", label: "Animal"},
73             {id: "IDKEYANIMALS", label: "Beast"},
74             {id: "IDKEYANIMALS", label: "Creature"},
75             {id: "IDKEYCOMMENT", label: "IDKEYCOMMENT"},
76             {id: "IDKEYSIZES", label: "Sizes"},
77             {id: "automation", label: "automation"},
78         ]);
79     });
80
81     it('returns the list of preferred tag keys', () => {
82         const preferredTagKeys = Vocabulary.getPreferredTags(vocabulary);
83         // Alphabetically ordered by label
84         expect(preferredTagKeys).toEqual([
85             {id: "IDKEYANIMALS", label: "Animal", synonyms: []},
86             {id: "IDKEYCOMMENT", label: "IDKEYCOMMENT", synonyms: []},
87             {id: "IDKEYSIZES", label: "Sizes", synonyms: []},
88             {id: "automation", label: "automation", synonyms: []},
89         ]);
90     });
91
92     it('returns the list of preferred tag keys with matching synonyms', () => {
93         const preferredTagKeys = Vocabulary.getPreferredTags(vocabulary, 'creat');
94         // Alphabetically ordered by label
95         expect(preferredTagKeys).toEqual([
96             {id: "IDKEYANIMALS", label: "Animal", synonyms: ["Creature"]},
97             {id: "IDKEYCOMMENT", label: "IDKEYCOMMENT", synonyms: []},
98             {id: "IDKEYSIZES", label: "Sizes", synonyms: []},
99             {id: "automation", label: "automation", synonyms: []},
100         ]);
101     });
102
103     it('returns the tag values for a given key', () => {
104         const tagValues = Vocabulary.getTagValues('IDKEYSIZES', vocabulary);
105         // Alphabetically ordered by label
106         expect(tagValues).toEqual([
107             {id: "IDVALSIZES4", label: "IDVALSIZES4"},
108             {id: "IDVALSIZES3", label: "L"},
109             {id: "IDVALSIZES3", label: "Large"},
110             {id: "IDVALSIZES1", label: "Little"},
111             {id: "IDVALSIZES2", label: "M"},
112             {id: "IDVALSIZES2", label: "Medium"},
113             {id: "IDVALSIZES1", label: "S"},
114             {id: "IDVALSIZES1", label: "Small"},
115         ]);
116         // Let's try a key that doesn't have any labels
117         const tagValues2 = Vocabulary.getTagValues('automation', vocabulary);
118         expect(tagValues2).toEqual([
119             {id: "results", label: "results"},
120             {id: "upload", label: "upload"},
121         ]);
122     });
123
124     it('returns the preferred tag values for a given key', () => {
125         const preferredTagValues = Vocabulary.getPreferredTagValues('IDKEYSIZES', vocabulary);
126         // Alphabetically ordered by label
127         expect(preferredTagValues).toEqual([
128             {id: "IDVALSIZES4", label: "IDVALSIZES4", synonyms: []},
129             {id: "IDVALSIZES3", label: "Large", synonyms: []},
130             {id: "IDVALSIZES2", label: "Medium", synonyms: []},
131             {id: "IDVALSIZES1", label: "Small", synonyms: []},
132         ]);
133         // Let's try a key that doesn't have any labels
134         const preferredTagValues2 = Vocabulary.getPreferredTagValues('automation', vocabulary);
135         expect(preferredTagValues2).toEqual([
136             {id: "results", label: "results", synonyms: []},
137             {id: "upload", label: "upload", synonyms: []},
138         ]);
139     });
140
141     it('returns the preferred tag values with matching synonyms for a given key', () => {
142         const preferredTagValues = Vocabulary.getPreferredTagValues('IDKEYSIZES', vocabulary, 'litt');
143         // Alphabetically ordered by label
144         expect(preferredTagValues).toEqual([
145             {id: "IDVALSIZES4", label: "IDVALSIZES4", synonyms: []},
146             {id: "IDVALSIZES3", label: "Large", synonyms: []},
147             {id: "IDVALSIZES2", label: "Medium", synonyms: []},
148             {id: "IDVALSIZES1", label: "Small", synonyms: ["Little"]},
149         ])
150     });
151
152     it('returns an empty list of values for an non-existent key', () => {
153         const tagValues = Vocabulary.getTagValues('IDNONSENSE', vocabulary);
154         expect(tagValues).toEqual([]);
155     });
156
157     it('returns a key id for a given key label', () => {
158         const testCases = [
159             // Two labels belonging to the same ID
160             {keyLabel: 'Animal', expected: 'IDKEYANIMALS'},
161             {keyLabel: 'Creature', expected: 'IDKEYANIMALS'},
162             // Non-existent label returns empty string
163             {keyLabel: 'ThisKeyLabelDoesntExist', expected: ''},
164             // Key with no labels still returns the key ID
165             {keyLabel: 'automation', expected: 'automation'},
166         ]
167         testCases.forEach(tc => {
168             const tagValueID = Vocabulary.getTagKeyID(tc.keyLabel, vocabulary);
169             expect(tagValueID).toEqual(tc.expected);
170         });
171     });
172
173     it('returns an key label for a given key id', () => {
174         const testCases = [
175             // ID with many labels return the first one
176             {keyID: 'IDKEYANIMALS', expected: 'Animal'},
177             // Key IDs without any labels or unknown keys should return the literal
178             // key from the API's response (that is, the key 'id')
179             {keyID: 'IDKEYCOMMENT', expected: 'IDKEYCOMMENT'},
180             {keyID: 'FOO', expected: 'FOO'},
181         ]
182         testCases.forEach(tc => {
183             const tagValueID = Vocabulary.getTagKeyLabel(tc.keyID, vocabulary);
184             expect(tagValueID).toEqual(tc.expected);
185         });
186     });
187
188     it('returns a value id for a given key id and value label', () => {
189         const testCases = [
190             // Key ID and value label known
191             {keyID: 'IDKEYANIMALS', valueLabel: 'Human', expected: 'IDVALANIMALS1'},
192             {keyID: 'IDKEYANIMALS', valueLabel: 'Homo sapiens', expected: 'IDVALANIMALS1'},
193             // Key ID known, value label unknown
194             {keyID: 'IDKEYANIMALS', valueLabel: 'Dinosaur', expected: ''},
195             // Key ID unknown
196             {keyID: 'IDNONSENSE', valueLabel: 'Does not matter', expected: ''},
197             // Value with no labels still returns the value ID
198             {keyID: 'automation', valueLabel: 'results', expected: 'results'},
199         ]
200         testCases.forEach(tc => {
201             const tagValueID = Vocabulary.getTagValueID(tc.keyID, tc.valueLabel, vocabulary);
202             expect(tagValueID).toEqual(tc.expected);
203         });
204     });
205
206     it('returns a value label for a given key & value id pair', () => {
207         const testCases = [
208             // Known key & value ids with multiple value labels: returns the first label
209             {keyId: 'IDKEYANIMALS', valueId: 'IDVALANIMALS1', expected: 'Human'},
210             // Values without label or unknown values should return the literal value from
211             // the API's response (that is, the value 'id')
212             {keyId: 'IDKEYSIZES', valueId: 'IDVALSIZES4', expected: 'IDVALSIZES4'},
213             {keyId: 'IDKEYCOMMENT', valueId: 'FOO', expected: 'FOO'},
214             {keyId: 'IDKEYANIMALS', valueId: 'BAR', expected: 'BAR'},
215             {keyId: 'IDKEYNONSENSE', valueId: 'FOOBAR', expected: 'FOOBAR'},
216         ]
217         testCases.forEach(tc => {
218             const tagValueLabel = Vocabulary.getTagValueLabel(tc.keyId, tc.valueId, vocabulary);
219             expect(tagValueLabel).toEqual(tc.expected);
220         });
221     });
222 });