WIP Add places to lists
This commit is contained in:
@@ -1,11 +1,35 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'marco/tests/helpers';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { render, click } from '@ember/test-helpers';
|
||||
import Service from '@ember/service';
|
||||
import PlaceDetails from 'marco/components/place-details';
|
||||
|
||||
module('Integration | Component | place-details', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
class StorageService extends Service {
|
||||
lists = [
|
||||
{ id: 'to-go', title: 'Want to go', color: '#ff00ff' },
|
||||
{ id: 'to-do', title: 'To do', color: '#008000' },
|
||||
];
|
||||
|
||||
async storePlace(place) {
|
||||
return { ...place, id: '123', createdAt: new Date().toISOString() };
|
||||
}
|
||||
|
||||
async removePlace() {
|
||||
return true;
|
||||
}
|
||||
|
||||
async togglePlaceList() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.owner.register('service:storage', StorageService);
|
||||
});
|
||||
|
||||
test('it formats coordinates correctly', async function (assert) {
|
||||
const place = {
|
||||
title: 'Test Place',
|
||||
@@ -34,4 +58,160 @@ module('Integration | Component | place-details', function (hooks) {
|
||||
assert.dom('.place-details h3').hasText('Place without Coords');
|
||||
assert.dom('.meta-info a[href*="geo:"]').doesNotExist();
|
||||
});
|
||||
|
||||
test('it reveals the list manager when save is clicked', async function (assert) {
|
||||
const place = {
|
||||
title: 'Cool Cafe',
|
||||
lat: 10,
|
||||
lon: 10,
|
||||
};
|
||||
|
||||
await render(<template><PlaceDetails @place={{place}} /></template>);
|
||||
|
||||
// Manager is initially hidden
|
||||
assert.dom('.place-lists-manager').doesNotExist();
|
||||
|
||||
// Find the Save button
|
||||
// It's the first button in .actions
|
||||
const saveBtn = this.element.querySelector('.actions button');
|
||||
await click(saveBtn);
|
||||
|
||||
// Manager should be visible now
|
||||
assert.dom('.place-lists-manager').exists();
|
||||
|
||||
// Check for default lists from mock service
|
||||
assert.dom('.place-lists-manager').includesText('Want to go');
|
||||
assert.dom('.place-lists-manager').includesText('To do');
|
||||
assert.dom('.place-lists-manager').includesText('Saved');
|
||||
});
|
||||
|
||||
test('it handles saving a new place via master toggle', async function (assert) {
|
||||
let storedPlace = null;
|
||||
|
||||
// Override mock service specifically for this test to spy on storePlace
|
||||
class MockStorage extends Service {
|
||||
lists = [];
|
||||
async storePlace(place) {
|
||||
storedPlace = place;
|
||||
return { ...place, id: 'new-id', createdAt: new Date().toISOString() };
|
||||
}
|
||||
}
|
||||
this.owner.register('service:storage', MockStorage);
|
||||
|
||||
const place = {
|
||||
title: 'New Spot',
|
||||
lat: 20,
|
||||
lon: 20,
|
||||
};
|
||||
|
||||
await render(<template><PlaceDetails @place={{place}} /></template>);
|
||||
|
||||
// Open manager
|
||||
await click('.actions button');
|
||||
|
||||
// Find master "Saved" toggle
|
||||
const masterToggle = this.element.querySelector(
|
||||
'.place-lists-manager .master-toggle input'
|
||||
);
|
||||
|
||||
// It should be unchecked initially for a new place
|
||||
assert.dom(masterToggle).isNotChecked();
|
||||
|
||||
// Click it to save
|
||||
await click(masterToggle);
|
||||
|
||||
// Verify storePlace was called
|
||||
assert.ok(storedPlace, 'storePlace was called');
|
||||
assert.strictEqual(storedPlace.title, 'New Spot');
|
||||
});
|
||||
|
||||
test('it handles removing a saved place via master toggle', async function (assert) {
|
||||
let removedPlace = null;
|
||||
let confirmCalled = false;
|
||||
|
||||
// Mock confirm
|
||||
const originalConfirm = window.confirm;
|
||||
window.confirm = () => {
|
||||
confirmCalled = true;
|
||||
return true;
|
||||
};
|
||||
|
||||
class MockStorage extends Service {
|
||||
lists = [];
|
||||
async removePlace(place) {
|
||||
removedPlace = place;
|
||||
}
|
||||
}
|
||||
this.owner.register('service:storage', MockStorage);
|
||||
|
||||
const place = {
|
||||
id: 'saved-id',
|
||||
title: 'Saved Spot',
|
||||
lat: 30,
|
||||
lon: 30,
|
||||
createdAt: '2023-01-01', // Marks it as saved
|
||||
};
|
||||
|
||||
await render(<template><PlaceDetails @place={{place}} /></template>);
|
||||
|
||||
// Open manager
|
||||
await click('.actions button');
|
||||
|
||||
// Find master "Saved" toggle
|
||||
const masterToggle = this.element.querySelector(
|
||||
'.place-lists-manager .master-toggle input'
|
||||
);
|
||||
|
||||
// It should be checked initially for a saved place
|
||||
assert.dom(masterToggle).isChecked();
|
||||
|
||||
// Click it to remove
|
||||
await click(masterToggle);
|
||||
|
||||
assert.ok(confirmCalled, 'confirm dialog was shown');
|
||||
assert.strictEqual(removedPlace.id, 'saved-id', 'removePlace was called');
|
||||
|
||||
// Restore confirm
|
||||
window.confirm = originalConfirm;
|
||||
});
|
||||
|
||||
test('it adds place to a list', async function (assert) {
|
||||
let listId = null;
|
||||
let placeArg = null;
|
||||
let shouldAdd = null;
|
||||
|
||||
class MockStorage extends Service {
|
||||
lists = [{ id: 'favs', title: 'Favorites', color: 'red' }];
|
||||
async togglePlaceList(place, id, add) {
|
||||
placeArg = place;
|
||||
listId = id;
|
||||
shouldAdd = add;
|
||||
}
|
||||
}
|
||||
this.owner.register('service:storage', MockStorage);
|
||||
|
||||
// Provide a place that is already saved
|
||||
const place = {
|
||||
id: 'p1',
|
||||
title: 'My Spot',
|
||||
createdAt: '2023-01-01',
|
||||
_listIds: [], // Not in any list yet
|
||||
};
|
||||
|
||||
await render(<template><PlaceDetails @place={{place}} /></template>);
|
||||
|
||||
// Open manager
|
||||
await click('.actions button');
|
||||
|
||||
// Find the checkbox for "Favorites"
|
||||
const checkbox = this.element.querySelectorAll(
|
||||
'.place-lists-manager input[type="checkbox"]'
|
||||
)[1]; // Index 1 because 0 is master toggle
|
||||
|
||||
await click(checkbox);
|
||||
|
||||
assert.strictEqual(listId, 'favs');
|
||||
assert.strictEqual(placeArg.id, 'p1');
|
||||
assert.true(shouldAdd);
|
||||
});
|
||||
});
|
||||
|
||||
58
tests/unit/utils/place-mapping-test.js
Normal file
58
tests/unit/utils/place-mapping-test.js
Normal file
@@ -0,0 +1,58 @@
|
||||
import { mapToStorageSchema } from 'marco/utils/place-mapping';
|
||||
import { module, test } from 'qunit';
|
||||
|
||||
module('Unit | Utility | place-mapping', function () {
|
||||
test('it maps a raw place object to the storage schema', function (assert) {
|
||||
const rawPlace = {
|
||||
osmId: 12345,
|
||||
osmType: 'node',
|
||||
lat: 52.52,
|
||||
lon: 13.405,
|
||||
osmTags: {
|
||||
name: 'Test Place',
|
||||
website: 'https://example.com',
|
||||
},
|
||||
description: 'A test description',
|
||||
};
|
||||
|
||||
const result = mapToStorageSchema(rawPlace);
|
||||
|
||||
assert.strictEqual(result.title, 'Test Place');
|
||||
assert.strictEqual(result.lat, 52.52);
|
||||
assert.strictEqual(result.lon, 13.405);
|
||||
assert.strictEqual(result.osmId, '12345');
|
||||
assert.strictEqual(result.osmType, 'node');
|
||||
assert.strictEqual(result.url, 'https://example.com');
|
||||
assert.strictEqual(result.description, 'A test description');
|
||||
assert.deepEqual(result.osmTags, rawPlace.osmTags);
|
||||
assert.deepEqual(result.tags, []);
|
||||
});
|
||||
|
||||
test('it prioritizes place.title over osmTags.name', function (assert) {
|
||||
const rawPlace = {
|
||||
osmId: 123,
|
||||
lat: 0,
|
||||
lon: 0,
|
||||
title: 'Custom Title',
|
||||
osmTags: {
|
||||
name: 'OSM Name',
|
||||
},
|
||||
};
|
||||
|
||||
const result = mapToStorageSchema(rawPlace);
|
||||
assert.strictEqual(result.title, 'Custom Title');
|
||||
});
|
||||
|
||||
test('it handles fallback title correctly when no name is present', function (assert) {
|
||||
const rawPlace = {
|
||||
id: 987,
|
||||
lat: 10,
|
||||
lon: 20,
|
||||
osmTags: {},
|
||||
};
|
||||
|
||||
const result = mapToStorageSchema(rawPlace);
|
||||
assert.strictEqual(result.title, 'Untitled Place');
|
||||
assert.strictEqual(result.osmId, '987');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user