Optionally add tag to place photo
This commit is contained in:
144
tests/unit/utils/nostr-test.js
Normal file
144
tests/unit/utils/nostr-test.js
Normal file
@@ -0,0 +1,144 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { normalizeRelayUrl, parsePlacePhotos } from 'marco/utils/nostr';
|
||||
|
||||
module('Unit | Utility | nostr', function () {
|
||||
test('normalizeRelayUrl normalizes protocol, case, and slashes', function (assert) {
|
||||
assert.strictEqual(normalizeRelayUrl(null), '');
|
||||
assert.strictEqual(normalizeRelayUrl(''), '');
|
||||
assert.strictEqual(normalizeRelayUrl(' '), '');
|
||||
|
||||
assert.strictEqual(
|
||||
normalizeRelayUrl('Relay.example.com'),
|
||||
'wss://relay.example.com'
|
||||
);
|
||||
assert.strictEqual(
|
||||
normalizeRelayUrl('ws://Relay.example.com/'),
|
||||
'ws://relay.example.com'
|
||||
);
|
||||
assert.strictEqual(
|
||||
normalizeRelayUrl('wss://relay.example.com///'),
|
||||
'wss://relay.example.com'
|
||||
);
|
||||
});
|
||||
|
||||
test('parsePlacePhotos includes event t tags on photo objects', function (assert) {
|
||||
const events = [
|
||||
{
|
||||
id: 'event-1',
|
||||
pubkey: 'pubkey-1',
|
||||
created_at: 123,
|
||||
tags: [
|
||||
['i', 'osm:node:123'],
|
||||
['t', 'food'],
|
||||
['t', 'vibe'],
|
||||
['imeta', 'url https://example.com/photo.jpg', 'dim 800x600'],
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const photos = parsePlacePhotos(events);
|
||||
|
||||
assert.strictEqual(photos.length, 1);
|
||||
assert.deepEqual(photos[0].tags, ['food', 'vibe']);
|
||||
});
|
||||
|
||||
test('parsePlacePhotos sorts by created_at', function (assert) {
|
||||
const events = [
|
||||
{
|
||||
id: 'event-2',
|
||||
pubkey: 'pubkey-2',
|
||||
created_at: 200,
|
||||
tags: [
|
||||
['i', 'osm:node:456'],
|
||||
['imeta', 'url https://example.com/late.jpg', 'dim 600x900'],
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'event-1',
|
||||
pubkey: 'pubkey-1',
|
||||
created_at: 100,
|
||||
tags: [
|
||||
['i', 'osm:node:123'],
|
||||
['imeta', 'url https://example.com/early.jpg', 'dim 600x900'],
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const photos = parsePlacePhotos(events);
|
||||
|
||||
assert.strictEqual(photos.length, 2);
|
||||
assert.strictEqual(photos[0].url, 'https://example.com/early.jpg');
|
||||
assert.strictEqual(photos[1].url, 'https://example.com/late.jpg');
|
||||
});
|
||||
|
||||
test('parsePlacePhotos promotes first landscape photo to index 0', function (assert) {
|
||||
const events = [
|
||||
{
|
||||
id: 'event-1',
|
||||
pubkey: 'pubkey-1',
|
||||
created_at: 100,
|
||||
tags: [
|
||||
['imeta', 'url https://example.com/portrait.jpg', 'dim 600x900'],
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'event-2',
|
||||
pubkey: 'pubkey-2',
|
||||
created_at: 200,
|
||||
tags: [
|
||||
['imeta', 'url https://example.com/landscape.jpg', 'dim 1200x600'],
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const photos = parsePlacePhotos(events);
|
||||
|
||||
assert.strictEqual(photos.length, 2);
|
||||
assert.strictEqual(photos[0].url, 'https://example.com/landscape.jpg');
|
||||
assert.strictEqual(photos[1].url, 'https://example.com/portrait.jpg');
|
||||
});
|
||||
|
||||
test('parsePlacePhotos skips imeta entries without urls', function (assert) {
|
||||
const events = [
|
||||
{
|
||||
id: 'event-1',
|
||||
pubkey: 'pubkey-1',
|
||||
created_at: 100,
|
||||
tags: [['imeta', 'dim 800x600']],
|
||||
},
|
||||
];
|
||||
|
||||
const photos = parsePlacePhotos(events);
|
||||
|
||||
assert.deepEqual(photos, []);
|
||||
});
|
||||
|
||||
test('parsePlacePhotos returns one photo per event imeta tag', function (assert) {
|
||||
const events = [
|
||||
{
|
||||
id: 'event-1',
|
||||
pubkey: 'pubkey-1',
|
||||
created_at: 100,
|
||||
tags: [
|
||||
['i', 'osm:node:123'],
|
||||
['imeta', 'url https://example.com/photo-1.jpg', 'dim 800x600'],
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'event-2',
|
||||
pubkey: 'pubkey-2',
|
||||
created_at: 200,
|
||||
tags: [
|
||||
['i', 'osm:node:456'],
|
||||
['imeta', 'url https://example.com/photo-2.jpg', 'dim 600x800'],
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const photos = parsePlacePhotos(events);
|
||||
|
||||
assert.strictEqual(photos.length, 2);
|
||||
assert.strictEqual(photos[0].placeIdentifier, 'osm:node:123');
|
||||
assert.strictEqual(photos[1].placeIdentifier, 'osm:node:456');
|
||||
});
|
||||
});
|
||||
30
tests/unit/utils/photo-tag-suggestions-test.js
Normal file
30
tests/unit/utils/photo-tag-suggestions-test.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { POI_CATEGORIES } from 'marco/utils/poi-categories';
|
||||
import { getMatchingPoiCategoryIds } from 'marco/utils/poi-category-matcher';
|
||||
import {
|
||||
getSuggestedPhotoTags,
|
||||
CATEGORY_TAGS,
|
||||
} from 'marco/utils/photo-tag-suggestions';
|
||||
|
||||
module('Unit | Utility | photo-tag-suggestions', function () {
|
||||
test('returns tags for all matching categories with de-duplication', function (assert) {
|
||||
const place = { osmTags: { amenity: 'cafe' } };
|
||||
const categoryIds = getMatchingPoiCategoryIds(
|
||||
place.osmTags,
|
||||
POI_CATEGORIES
|
||||
);
|
||||
|
||||
assert.ok(categoryIds.includes('restaurants'));
|
||||
assert.ok(categoryIds.includes('coffee'));
|
||||
|
||||
const result = getSuggestedPhotoTags(place);
|
||||
assert.deepEqual(result, CATEGORY_TAGS.restaurants);
|
||||
});
|
||||
|
||||
test('returns no tags when no category matches', function (assert) {
|
||||
const place = { osmTags: { office: 'lawyer' } };
|
||||
const result = getSuggestedPhotoTags(place);
|
||||
|
||||
assert.deepEqual(result, []);
|
||||
});
|
||||
});
|
||||
38
tests/unit/utils/poi-category-matcher-test.js
Normal file
38
tests/unit/utils/poi-category-matcher-test.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { POI_CATEGORIES } from 'marco/utils/poi-categories';
|
||||
import {
|
||||
getMatchingPoiCategories,
|
||||
getMatchingPoiCategoryIds,
|
||||
} from 'marco/utils/poi-category-matcher';
|
||||
|
||||
module('Unit | Utility | poi-category-matcher', function () {
|
||||
test('matches multiple categories from OSM tags', function (assert) {
|
||||
const tags = { amenity: 'cafe' };
|
||||
const categoryIds = getMatchingPoiCategoryIds(tags, POI_CATEGORIES);
|
||||
|
||||
assert.ok(categoryIds.includes('restaurants'));
|
||||
assert.ok(categoryIds.includes('coffee'));
|
||||
});
|
||||
|
||||
test('supports semicolon-separated values', function (assert) {
|
||||
const tags = { amenity: 'cafe;bar' };
|
||||
const categoryIds = getMatchingPoiCategoryIds(tags, POI_CATEGORIES);
|
||||
|
||||
assert.ok(categoryIds.includes('coffee'));
|
||||
});
|
||||
|
||||
test('negative regex clause fails if any value matches', function (assert) {
|
||||
const tags = { amenity: 'cafe', cuisine: 'coffee;irish' };
|
||||
const categoryIds = getMatchingPoiCategoryIds(tags, POI_CATEGORIES);
|
||||
|
||||
assert.notOk(categoryIds.includes('restaurants'));
|
||||
});
|
||||
|
||||
test('presence clause matches when tag exists', function (assert) {
|
||||
const tags = { historic: 'castle' };
|
||||
const categories = getMatchingPoiCategories(tags, POI_CATEGORIES);
|
||||
const categoryIds = categories.map((category) => category.id);
|
||||
|
||||
assert.ok(categoryIds.includes('things-to-do'));
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user