diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..24c3fe470 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,17 @@ +dist: focal +language: node_js +node_js: + - "18" + +# Specify branches that should be built +branches: + only: + - main + - scofield_map_update + +# Define the script to run for tests +script: + - yarn --frozen-lockfile + - yarn test + + diff --git a/package.json b/package.json index b68a0bea1..df702ae4d 100644 --- a/package.json +++ b/package.json @@ -157,7 +157,7 @@ "workbox-precaching": "^7.0.0" }, "engines": { - "node": ">= 16", + "node": ">= 18", "npm": ">= 6.13.4", "yarn": ">= 1.21.1" }, diff --git a/some-file.txt b/some-file.txt new file mode 100644 index 000000000..f1ab353d0 --- /dev/null +++ b/some-file.txt @@ -0,0 +1,2 @@ +// Trigger build +// Trigger build diff --git a/src/maps/components/KMarker.vue b/src/maps/components/KMarker.vue index f706d5f32..4e0eac6ba 100644 --- a/src/maps/components/KMarker.vue +++ b/src/maps/components/KMarker.vue @@ -56,6 +56,7 @@ export default { }, emits: [ 'dragend', + 'marker-clicked', ], setup () { const leafletMap = inject('leafletMap') @@ -96,6 +97,11 @@ export default { draggable: this.draggable, }).addTo(this.leafletMap)) + this.leafletMarker.on('click', event => { + // If user click the marker, it would enter localselectMarker array + this.$emit('marker-clicked', event) + }) + if (this.opacity) { this.leafletMarker.setOpacity(this.opacity) } diff --git a/src/maps/components/StandardMap.spec.js b/src/maps/components/StandardMap.spec.js index fca630ade..c40a3b87c 100644 --- a/src/maps/components/StandardMap.spec.js +++ b/src/maps/components/StandardMap.spec.js @@ -1,37 +1,133 @@ -import { flushPromises } from '@vue/test-utils' +import { flushPromises, mount } from '@vue/test-utils' import { vi } from 'vitest' -import GroupMarker from '@/maps/components/GroupMarker.vue' import KMap from '@/maps/components/KMap.vue' import KMarker from '@/maps/components/KMarker.vue' -import { makeGroup } from '>/enrichedFactories' -import { mountWithDefaults } from '>/helpers' - import StandardMap from './StandardMap.vue' -import { groupMarker } from './markers' -const markers = [...Array(20).keys()].map(e => groupMarker(makeGroup())) +// Define a utility to create a mock marker +function createMockMarker (id) { + return { + id, + latLng: { lat: Math.random() * 100, lng: Math.random() * 100 }, + popup: 'Test Marker ' + id, + color: 'blue', + fontIcon: 'marker-icon', + click_count: 0, // Initialize click_count here + } +} + +// Custom equality checker for markers +function containsMarker (container, marker) { + return container.some(m => m.id === marker.id) +} describe('StandardMap', () => { - beforeEach(() => { vi.resetModules() }) - it('renders markers with popups', async () => { - const wrapper = await mountWithDefaults(StandardMap, { - propsData: { - markers, + let wrapper + let markers + + beforeEach(() => { + vi.resetModules() + markers = [createMockMarker(1), createMockMarker(2), createMockMarker(3), createMockMarker(4)] + wrapper = mount(StandardMap, { + props: { markers }, + global: { + stubs: { KMap }, // Stub KMap to isolate the component test }, }) + }) + + it('selects a marker and updates localSelectedMarkers', async () => { + const kMarker = wrapper.findAllComponents(KMarker).at(0) + await kMarker.vm.$emit('marker-clicked', { marker: markers[0] }) await flushPromises() - expect(wrapper.findAllComponents(KMap).length).toBe(1) - expect(wrapper.findAllComponents(KMarker).length).toBe(markers.length) - expect(wrapper.findAllComponents(GroupMarker).length).toBe(markers.length) - // add and remove some markers + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[0])).toBe(true) + expect(wrapper.emitted()['update:selectedMarkers'][0]).toEqual([[markers[0]]]) + }) + + it('toggles the selection state on repeated clicks', async () => { + const kMarker = wrapper.findAllComponents(KMarker).at(0) + // Simulate clicking the marker three times for (let i = 0; i < 3; i++) { - await wrapper.setProps({ markers: markers.filter((e, idx) => idx !== i) }) + await kMarker.vm.$emit('marker-clicked', { marker: markers[0] }) await flushPromises() - expect(wrapper.findAllComponents(KMarker).length).toBe(markers.length - 1) - expect(wrapper.findAllComponents(GroupMarker).length).toBe(markers.length - 1) } + + // Check if the toggle works correctly (should end up selected since it's an odd number of clicks) + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[0])).toBe(true) + expect(wrapper.vm.localSelectedMarkers).toHaveLength(1) + expect(markers[0].click_count).toBe(3) + }) + + it('changes selected marker and verifies the update', async () => { + const kMarkers = wrapper.findAllComponents(KMarker) + + // Select the first marker + await kMarkers.at(0).vm.$emit('marker-clicked', { marker: markers[0] }) + await flushPromises() + + // Select the second marker + await kMarkers.at(1).vm.$emit('marker-clicked', { marker: markers[1] }) + await flushPromises() + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[0])).toBe(false) + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[1])).toBe(true) + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[2])).toBe(false) + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[3])).toBe(false) + expect(wrapper.vm.localSelectedMarkers).not.toContain(markers[0]) + expect(wrapper.vm.localSelectedMarkers).not.toContain(markers[2]) + expect(wrapper.vm.localSelectedMarkers).not.toContain(markers[3]) + expect(wrapper.emitted()['update:selectedMarkers'][1]).toEqual([[markers[1]]]) + + // Select the third marker + await kMarkers.at(2).vm.$emit('marker-clicked', { marker: markers[2] }) + await flushPromises() + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[0])).toBe(false) + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[1])).toBe(false) + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[2])).toBe(true) + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[3])).toBe(false) + expect(wrapper.vm.localSelectedMarkers).not.toContain(markers[0]) + expect(wrapper.vm.localSelectedMarkers).not.toContain(markers[1]) + expect(wrapper.vm.localSelectedMarkers).not.toContain(markers[3]) + expect(wrapper.emitted()['update:selectedMarkers'][2]).toEqual([[markers[2]]]) + + // Select the fourth marker + await kMarkers.at(3).vm.$emit('marker-clicked', { marker: markers[1] }) + await flushPromises() + + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[0])).toBe(false) + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[1])).toBe(false) + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[2])).toBe(false) + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[3])).toBe(true) + expect(wrapper.vm.localSelectedMarkers).not.toContain(markers[0]) + expect(wrapper.vm.localSelectedMarkers).not.toContain(markers[1]) + expect(wrapper.vm.localSelectedMarkers).not.toContain(markers[2]) + expect(wrapper.emitted()['update:selectedMarkers'][3]).toEqual([[markers[3]]]) + + // Select back to the first marker + await kMarkers.at(0).vm.$emit('marker-clicked', { marker: markers[0] }) + await flushPromises() + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[0])).toBe(true) + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[1])).toBe(false) + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[2])).toBe(false) + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[3])).toBe(false) + expect(wrapper.vm.localSelectedMarkers).not.toContain(markers[1]) + expect(wrapper.vm.localSelectedMarkers).not.toContain(markers[2]) + expect(wrapper.vm.localSelectedMarkers).not.toContain(markers[3]) + expect(wrapper.emitted()['update:selectedMarkers'][0]).toEqual([[markers[0]]]) + + // Select back to the fourth marker + await kMarkers.at(1).vm.$emit('marker-clicked', { marker: markers[1] }) + await flushPromises() + + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[0])).toBe(false) + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[1])).toBe(true) + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[2])).toBe(false) + expect(containsMarker(wrapper.vm.localSelectedMarkers, markers[3])).toBe(false) + expect(wrapper.vm.localSelectedMarkers).not.toContain(markers[0]) + expect(wrapper.vm.localSelectedMarkers).not.toContain(markers[2]) + expect(wrapper.vm.localSelectedMarkers).not.toContain(markers[3]) + expect(wrapper.emitted()['update:selectedMarkers'][1]).toEqual([[markers[1]]]) }) }) diff --git a/src/maps/components/StandardMap.vue b/src/maps/components/StandardMap.vue index fe88fa3ff..bf107137c 100644 --- a/src/maps/components/StandardMap.vue +++ b/src/maps/components/StandardMap.vue @@ -1,5 +1,6 @@