mirror of
				https://github.com/dwaxweiler/connector-mobilizon
				synced 2025-06-05 21:59:25 +02:00 
			
		
		
		
	remove unneeded folder
This commit is contained in:
		
							
								
								
									
										87
									
								
								source/front/date-time-wrapper-test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								source/front/date-time-wrapper-test.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
import test from 'ava'
 | 
			
		||||
import DateTimeWrapper from './date-time-wrapper'
 | 
			
		||||
 | 
			
		||||
test('#getShortDate usual date', (t) => {
 | 
			
		||||
  const d = new DateTimeWrapper({ text: '2020-12-24T16:45:00Z' })
 | 
			
		||||
  t.is(d.getShortDate(), '24/12/2020')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#getShortDate usual date with timezone string', (t) => {
 | 
			
		||||
  const d = new DateTimeWrapper({
 | 
			
		||||
    text: '2020-12-24T16:45:00Z',
 | 
			
		||||
    timeZone: 'Europe/Rome',
 | 
			
		||||
  })
 | 
			
		||||
  t.is(d.getShortDate(), '24/12/2020')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#getShortDate usual date with fixed offset', (t) => {
 | 
			
		||||
  const d = new DateTimeWrapper({
 | 
			
		||||
    text: '2020-12-24T16:45:00Z',
 | 
			
		||||
    timeZone: 'UTC+02:00',
 | 
			
		||||
  })
 | 
			
		||||
  t.is(d.getShortDate(), '24/12/2020')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#getShortDate usual date with fixed offset without UTC prefix', (t) => {
 | 
			
		||||
  const d = new DateTimeWrapper({
 | 
			
		||||
    text: '2020-12-24T16:45:00Z',
 | 
			
		||||
    timeZone: '+02:00',
 | 
			
		||||
  })
 | 
			
		||||
  t.is(d.getShortDate(), '24/12/2020')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#getShortDate usual date with empty time zone', (t) => {
 | 
			
		||||
  const d = new DateTimeWrapper({ text: '2020-12-24T16:45:00Z', timeZone: '' })
 | 
			
		||||
  t.is(d.getShortDate(), '24/12/2020')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#get24Time usual time', (t) => {
 | 
			
		||||
  const d = new DateTimeWrapper({ text: '2020-12-24T16:45:00Z' })
 | 
			
		||||
  t.is(d.get24Time(), '16:45')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#equalsDate same date, different time', (t) => {
 | 
			
		||||
  const d = new DateTimeWrapper({ text: '2020-12-24T16:45:00Z' })
 | 
			
		||||
  const e = new DateTimeWrapper({ text: '2020-12-24T17:46:01Z' })
 | 
			
		||||
  t.true(d.equalsDate(e))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#equalsDate different date, different time', (t) => {
 | 
			
		||||
  const d = new DateTimeWrapper({ text: '2020-12-24T16:45:00Z' })
 | 
			
		||||
  const e = new DateTimeWrapper({ text: '2021-11-25T17:46:01Z' })
 | 
			
		||||
  t.false(d.equalsDate(e))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#equalsDate different day, different time', (t) => {
 | 
			
		||||
  const d = new DateTimeWrapper({ text: '2020-12-24T16:45:00Z' })
 | 
			
		||||
  const e = new DateTimeWrapper({ text: '2020-12-25T17:46:01Z' })
 | 
			
		||||
  t.false(d.equalsDate(e))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#equalsDate different month, different time', (t) => {
 | 
			
		||||
  const d = new DateTimeWrapper({ text: '2020-12-24T16:45:00Z' })
 | 
			
		||||
  const e = new DateTimeWrapper({ text: '2020-11-24T17:46:01Z' })
 | 
			
		||||
  t.false(d.equalsDate(e))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#equalsDate different year, different time', (t) => {
 | 
			
		||||
  const d = new DateTimeWrapper({ text: '2020-12-24T16:45:00Z' })
 | 
			
		||||
  const e = new DateTimeWrapper({ text: '2021-12-24T17:46:01Z' })
 | 
			
		||||
  t.false(d.equalsDate(e))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#getCurrentDatetimeAsString correct format', (t) => {
 | 
			
		||||
  const d = DateTimeWrapper.getCurrentDatetimeAsString()
 | 
			
		||||
  t.is(d[4], '-')
 | 
			
		||||
  t.is(d[7], '-')
 | 
			
		||||
  t.is(d[10], 'T')
 | 
			
		||||
  t.is(d[13], ':')
 | 
			
		||||
  t.is(d[16], ':')
 | 
			
		||||
  t.is(d[19], '.')
 | 
			
		||||
  t.is(d[d.length - 3], ':')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#getShortOffsetName usual time', (t) => {
 | 
			
		||||
  const d = new DateTimeWrapper({ text: '2020-12-24T16:45:00Z' })
 | 
			
		||||
  t.is(d.getShortOffsetName(), 'UTC')
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										42
									
								
								source/front/date-time-wrapper.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								source/front/date-time-wrapper.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
import { DateTime } from 'luxon'
 | 
			
		||||
 | 
			
		||||
export default class DateTimeWrapper {
 | 
			
		||||
  constructor({ locale = 'en-GB', text, timeZone = 'utc' } = {}) {
 | 
			
		||||
    if (!timeZone) {
 | 
			
		||||
      timeZone = 'utc'
 | 
			
		||||
    }
 | 
			
		||||
    if (
 | 
			
		||||
      timeZone.includes(':') &&
 | 
			
		||||
      timeZone.substring(0, 3).toUpperCase() !== 'UTC'
 | 
			
		||||
    ) {
 | 
			
		||||
      timeZone = 'UTC' + timeZone
 | 
			
		||||
    }
 | 
			
		||||
    this.dateTime = DateTime.fromISO(text, { locale, zone: timeZone })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getShortDate() {
 | 
			
		||||
    return this.dateTime.toLocaleString(DateTime.DATE_SHORT)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getShortOffsetName() {
 | 
			
		||||
    return this.dateTime.offsetNameShort
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get24Time() {
 | 
			
		||||
    return this.dateTime.toLocaleString(DateTime.TIME_24_SIMPLE)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  equalsDate(other) {
 | 
			
		||||
    return (
 | 
			
		||||
      this.dateTime &&
 | 
			
		||||
      other.dateTime &&
 | 
			
		||||
      this.dateTime.day === other.dateTime.day &&
 | 
			
		||||
      this.dateTime.month === other.dateTime.month &&
 | 
			
		||||
      this.dateTime.year === other.dateTime.year
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static getCurrentDatetimeAsString() {
 | 
			
		||||
    return DateTime.now().toString()
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										81
									
								
								source/front/events-displayer-test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								source/front/events-displayer-test.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
import test from 'ava'
 | 
			
		||||
import { JSDOM } from 'jsdom'
 | 
			
		||||
 | 
			
		||||
import { displayEvents, displayErrorMessage } from './events-displayer'
 | 
			
		||||
 | 
			
		||||
let document
 | 
			
		||||
 | 
			
		||||
test.before(() => {
 | 
			
		||||
  document = new JSDOM().window.document
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test.beforeEach((t) => {
 | 
			
		||||
  t.context.list = document.createElement('ul')
 | 
			
		||||
  t.context.list.setAttribute('data-locale', 'en-GB')
 | 
			
		||||
  t.context.list.setAttribute('data-maximum', '2')
 | 
			
		||||
  t.context.list.setAttribute('data-time-zone', 'utc')
 | 
			
		||||
  const listElement = document.createElement('li')
 | 
			
		||||
  listElement.setAttribute('style', 'display: none;')
 | 
			
		||||
  t.context.list.appendChild(listElement)
 | 
			
		||||
  const listElement2 = document.createElement('li')
 | 
			
		||||
  listElement2.setAttribute('style', 'display: none;')
 | 
			
		||||
  t.context.list.appendChild(listElement2)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#displayEvents one event', (t) => {
 | 
			
		||||
  const list = t.context.list
 | 
			
		||||
  const data = {
 | 
			
		||||
    events: {
 | 
			
		||||
      elements: [
 | 
			
		||||
        {
 | 
			
		||||
          title: 'a',
 | 
			
		||||
          url: 'b',
 | 
			
		||||
          beginsOn: '2021-04-15T10:30:00Z',
 | 
			
		||||
          endsOn: '2021-04-15T15:30:00Z',
 | 
			
		||||
          physicalAddress: {
 | 
			
		||||
            description: 'c',
 | 
			
		||||
            locality: 'd',
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
    },
 | 
			
		||||
  }
 | 
			
		||||
  displayEvents({ data, document, list })
 | 
			
		||||
  t.is(list.children.length, 3)
 | 
			
		||||
  t.is(list.children[2].childNodes[0].tagName, 'A')
 | 
			
		||||
  t.is(list.children[2].childNodes[0].getAttribute('href'), 'b')
 | 
			
		||||
  t.is(list.children[2].childNodes[0].childNodes[0].nodeValue, 'a')
 | 
			
		||||
  t.is(list.children[2].childNodes[1].tagName, 'BR')
 | 
			
		||||
  t.is(list.children[2].childNodes[2].nodeValue, '15/04/2021 10:30 - 15:30')
 | 
			
		||||
  t.is(list.children[2].childNodes[3].tagName, 'BR')
 | 
			
		||||
  t.is(list.children[2].childNodes[4].nodeValue, 'c, d')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#displayErrorMessage no children added', (t) => {
 | 
			
		||||
  const list = t.context.list
 | 
			
		||||
  displayErrorMessage({ data: '', list })
 | 
			
		||||
  t.is(list.children.length, 2)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#displayErrorMessage error message display', (t) => {
 | 
			
		||||
  const list = t.context.list
 | 
			
		||||
  displayErrorMessage({ data: '', list })
 | 
			
		||||
  t.is(list.children[0].style.display, 'block')
 | 
			
		||||
  t.is(list.children[1].style.display, 'none')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#displayErrorMessage group not found error message display', (t) => {
 | 
			
		||||
  const list = t.context.list
 | 
			
		||||
  const data = {
 | 
			
		||||
    response: {
 | 
			
		||||
      errors: [
 | 
			
		||||
        {
 | 
			
		||||
          code: 'group_not_found',
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
    },
 | 
			
		||||
  }
 | 
			
		||||
  displayErrorMessage({ data, list })
 | 
			
		||||
  t.is(list.children[0].style.display, 'none')
 | 
			
		||||
  t.is(list.children[1].style.display, 'block')
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										69
									
								
								source/front/events-displayer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								source/front/events-displayer.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
import Formatter from './formatter'
 | 
			
		||||
import { createAnchorElement } from './html-creator'
 | 
			
		||||
 | 
			
		||||
export function displayEvents({ data, document, list }) {
 | 
			
		||||
  const locale = list.getAttribute('data-locale')
 | 
			
		||||
  const maxEventsCount = list.getAttribute('data-maximum')
 | 
			
		||||
  const timeZone = list.getAttribute('data-time-zone')
 | 
			
		||||
  const isShortOffsetNameShown = list.hasAttribute(
 | 
			
		||||
    'data-is-short-offset-name-shown'
 | 
			
		||||
  )
 | 
			
		||||
  const events = data.events
 | 
			
		||||
    ? data.events.elements
 | 
			
		||||
    : data.group.organizedEvents.elements
 | 
			
		||||
  const eventsCount = Math.min(maxEventsCount, events.length)
 | 
			
		||||
  for (let i = 0; i < eventsCount; i++) {
 | 
			
		||||
    const li = document.createElement('li')
 | 
			
		||||
 | 
			
		||||
    const a = createAnchorElement({
 | 
			
		||||
      document,
 | 
			
		||||
      text: events[i].title,
 | 
			
		||||
      url: events[i].url,
 | 
			
		||||
    })
 | 
			
		||||
    li.appendChild(a)
 | 
			
		||||
 | 
			
		||||
    const br = document.createElement('br')
 | 
			
		||||
    li.appendChild(br)
 | 
			
		||||
 | 
			
		||||
    const date = Formatter.formatDate({
 | 
			
		||||
      locale,
 | 
			
		||||
      start: events[i].beginsOn,
 | 
			
		||||
      end: events[i].endsOn,
 | 
			
		||||
      timeZone,
 | 
			
		||||
      isShortOffsetNameShown,
 | 
			
		||||
    })
 | 
			
		||||
    const textnode = document.createTextNode(date)
 | 
			
		||||
    li.appendChild(textnode)
 | 
			
		||||
 | 
			
		||||
    if (events[i].physicalAddress) {
 | 
			
		||||
      const location = Formatter.formatLocation({
 | 
			
		||||
        description: events[i].physicalAddress.description,
 | 
			
		||||
        locality: events[i].physicalAddress.locality,
 | 
			
		||||
      })
 | 
			
		||||
      if (location) {
 | 
			
		||||
        const brBeforeLocation = document.createElement('br')
 | 
			
		||||
        li.appendChild(brBeforeLocation)
 | 
			
		||||
 | 
			
		||||
        const textnodeLocation = document.createTextNode(location)
 | 
			
		||||
        li.appendChild(textnodeLocation)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    list.appendChild(li)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function displayErrorMessage({ data, list }) {
 | 
			
		||||
  console.error(data)
 | 
			
		||||
  if (
 | 
			
		||||
    Object.prototype.hasOwnProperty.call(data, 'response') &&
 | 
			
		||||
    Object.prototype.hasOwnProperty.call(data.response, 'errors') &&
 | 
			
		||||
    data.response.errors.length > 0 &&
 | 
			
		||||
    Object.prototype.hasOwnProperty.call(data.response.errors[0], 'code') &&
 | 
			
		||||
    data.response.errors[0].code === 'group_not_found'
 | 
			
		||||
  ) {
 | 
			
		||||
    list.children[1].style.display = 'block'
 | 
			
		||||
  } else {
 | 
			
		||||
    list.children[0].style.display = 'block'
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								source/front/events-loader.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								source/front/events-loader.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
import { displayEvents, displayErrorMessage } from './events-displayer'
 | 
			
		||||
import * as GraphqlWrapper from './graphql-wrapper'
 | 
			
		||||
 | 
			
		||||
const NAME = '<wordpress-name>'
 | 
			
		||||
 | 
			
		||||
document.addEventListener('DOMContentLoaded', () => {
 | 
			
		||||
  const eventLists = document.getElementsByClassName(NAME + '_events-list')
 | 
			
		||||
  for (const list of eventLists) {
 | 
			
		||||
    const url = list.getAttribute('data-url') + '/api'
 | 
			
		||||
    const limit = parseInt(list.getAttribute('data-maximum'))
 | 
			
		||||
    const groupName = list.getAttribute('data-group-name')
 | 
			
		||||
    if (groupName) {
 | 
			
		||||
      GraphqlWrapper.getUpcomingEventsByGroupName({ url, limit, groupName })
 | 
			
		||||
        .then((data) => displayEvents({ data, document, list }))
 | 
			
		||||
        .catch((data) => displayErrorMessage({ data, list }))
 | 
			
		||||
    } else {
 | 
			
		||||
      GraphqlWrapper.getUpcomingEvents({ url, limit })
 | 
			
		||||
        .then((data) => displayEvents({ data, document, list }))
 | 
			
		||||
        .catch((data) => displayErrorMessage({ data, list }))
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										51
									
								
								source/front/formatter-test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								source/front/formatter-test.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
import test from 'ava'
 | 
			
		||||
import Formatter from './formatter'
 | 
			
		||||
 | 
			
		||||
test('#formatDate one date', (t) => {
 | 
			
		||||
  const date = Formatter.formatDate({
 | 
			
		||||
    start: '2021-04-15T10:30:00Z',
 | 
			
		||||
    end: '2021-04-15T15:30:00Z',
 | 
			
		||||
  })
 | 
			
		||||
  t.is(date, '15/04/2021 10:30 - 15:30')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#formatDate one date with short offset name', (t) => {
 | 
			
		||||
  const date = Formatter.formatDate({
 | 
			
		||||
    start: '2021-04-15T10:30:00Z',
 | 
			
		||||
    end: '2021-04-15T15:30:00Z',
 | 
			
		||||
    isShortOffsetNameShown: true,
 | 
			
		||||
  })
 | 
			
		||||
  t.is(date, '15/04/2021 10:30 - 15:30 (UTC)')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#formatDate two dates', (t) => {
 | 
			
		||||
  const date = Formatter.formatDate({
 | 
			
		||||
    start: '2021-04-15T10:30:00Z',
 | 
			
		||||
    end: '2021-04-16T15:30:00Z',
 | 
			
		||||
  })
 | 
			
		||||
  t.is(date, '15/04/2021 10:30 - 16/04/2021 15:30')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#formatDate two dates with short offset name', (t) => {
 | 
			
		||||
  const date = Formatter.formatDate({
 | 
			
		||||
    start: '2021-04-15T10:30:00Z',
 | 
			
		||||
    end: '2021-04-16T15:30:00Z',
 | 
			
		||||
    isShortOffsetNameShown: true,
 | 
			
		||||
  })
 | 
			
		||||
  t.is(date, '15/04/2021 10:30 (UTC) - 16/04/2021 15:30 (UTC)')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#formatLocation both parameters', (t) => {
 | 
			
		||||
  const date = Formatter.formatLocation({ description: 'a', locality: 'b' })
 | 
			
		||||
  t.is(date, 'a, b')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#formatLocation description only', (t) => {
 | 
			
		||||
  const date = Formatter.formatLocation({ description: 'a' })
 | 
			
		||||
  t.is(date, 'a')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#formatLocation locality only', (t) => {
 | 
			
		||||
  const date = Formatter.formatLocation({ locality: 'a' })
 | 
			
		||||
  t.is(date, 'a')
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										42
									
								
								source/front/formatter.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								source/front/formatter.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
import DateTimeWrapper from './date-time-wrapper'
 | 
			
		||||
 | 
			
		||||
export default class Formatter {
 | 
			
		||||
  static formatDate({ locale, timeZone, start, end, isShortOffsetNameShown }) {
 | 
			
		||||
    const startDateTime = new DateTimeWrapper({
 | 
			
		||||
      locale,
 | 
			
		||||
      text: start,
 | 
			
		||||
      timeZone,
 | 
			
		||||
    })
 | 
			
		||||
    const endDateTime = new DateTimeWrapper({ locale, text: end, timeZone })
 | 
			
		||||
    let dateText = startDateTime.getShortDate()
 | 
			
		||||
    dateText += ' ' + startDateTime.get24Time()
 | 
			
		||||
    if (!startDateTime.equalsDate(endDateTime)) {
 | 
			
		||||
      if (isShortOffsetNameShown) {
 | 
			
		||||
        dateText += ' (' + startDateTime.getShortOffsetName() + ')'
 | 
			
		||||
      }
 | 
			
		||||
      dateText += ' - '
 | 
			
		||||
      dateText += endDateTime.getShortDate() + ' '
 | 
			
		||||
    } else {
 | 
			
		||||
      dateText += ' - '
 | 
			
		||||
    }
 | 
			
		||||
    dateText += endDateTime.get24Time()
 | 
			
		||||
    if (isShortOffsetNameShown) {
 | 
			
		||||
      dateText += ' (' + endDateTime.getShortOffsetName() + ')'
 | 
			
		||||
    }
 | 
			
		||||
    return dateText
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static formatLocation({ description, locality }) {
 | 
			
		||||
    let location = ''
 | 
			
		||||
    if (description) {
 | 
			
		||||
      location += description
 | 
			
		||||
    }
 | 
			
		||||
    if (location && locality) {
 | 
			
		||||
      location += ', '
 | 
			
		||||
    }
 | 
			
		||||
    if (locality) {
 | 
			
		||||
      location += locality
 | 
			
		||||
    }
 | 
			
		||||
    return location
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										78
									
								
								source/front/graphql-wrapper.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								source/front/graphql-wrapper.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
import SessionCache from './session-cache'
 | 
			
		||||
import { request } from 'graphql-request'
 | 
			
		||||
import DateTimeWrapper from './date-time-wrapper'
 | 
			
		||||
 | 
			
		||||
export function getUpcomingEvents({ url, limit }) {
 | 
			
		||||
  const query = `
 | 
			
		||||
    query ($limit: Int) {
 | 
			
		||||
      events(limit: $limit) {
 | 
			
		||||
        elements {
 | 
			
		||||
          id,
 | 
			
		||||
          title,
 | 
			
		||||
          url,
 | 
			
		||||
          beginsOn,
 | 
			
		||||
          endsOn,
 | 
			
		||||
          physicalAddress {
 | 
			
		||||
            description,
 | 
			
		||||
            locality
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        total
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  `
 | 
			
		||||
  const dataInCache = SessionCache.get(sessionStorage, {
 | 
			
		||||
    url,
 | 
			
		||||
    query,
 | 
			
		||||
    variables: { limit },
 | 
			
		||||
  })
 | 
			
		||||
  if (dataInCache !== null) {
 | 
			
		||||
    return Promise.resolve(dataInCache)
 | 
			
		||||
  }
 | 
			
		||||
  return request(url, query, { limit }).then((data) => {
 | 
			
		||||
    SessionCache.add(sessionStorage, { url, query, variables: { limit } }, data)
 | 
			
		||||
    return Promise.resolve(data)
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getUpcomingEventsByGroupName({ url, limit, groupName }) {
 | 
			
		||||
  const query = `
 | 
			
		||||
    query ($afterDatetime: DateTime, $groupName: String, $limit: Int) {
 | 
			
		||||
      group(preferredUsername: $groupName) {
 | 
			
		||||
        organizedEvents(afterDatetime: $afterDatetime, limit: $limit) {
 | 
			
		||||
          elements {
 | 
			
		||||
            id,
 | 
			
		||||
            title,
 | 
			
		||||
            url,
 | 
			
		||||
            beginsOn,
 | 
			
		||||
            endsOn,
 | 
			
		||||
            physicalAddress {
 | 
			
		||||
              description,
 | 
			
		||||
              locality
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          total
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  `
 | 
			
		||||
  const afterDatetime = DateTimeWrapper.getCurrentDatetimeAsString()
 | 
			
		||||
  const dataInCache = SessionCache.get(sessionStorage, {
 | 
			
		||||
    url,
 | 
			
		||||
    query,
 | 
			
		||||
    variables: { afterDatetime, groupName, limit },
 | 
			
		||||
  })
 | 
			
		||||
  if (dataInCache !== null) {
 | 
			
		||||
    return Promise.resolve(dataInCache)
 | 
			
		||||
  }
 | 
			
		||||
  return request(url, query, { afterDatetime, groupName, limit }).then(
 | 
			
		||||
    (data) => {
 | 
			
		||||
      SessionCache.add(
 | 
			
		||||
        sessionStorage,
 | 
			
		||||
        { url, query, variables: { afterDatetime, groupName, limit } },
 | 
			
		||||
        data
 | 
			
		||||
      )
 | 
			
		||||
      return Promise.resolve(data)
 | 
			
		||||
    }
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								source/front/html-creator-test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								source/front/html-creator-test.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
import test from 'ava'
 | 
			
		||||
import { JSDOM } from 'jsdom'
 | 
			
		||||
 | 
			
		||||
import { createAnchorElement } from './html-creator'
 | 
			
		||||
 | 
			
		||||
let document
 | 
			
		||||
 | 
			
		||||
test.beforeEach(() => {
 | 
			
		||||
  document = new JSDOM().window.document
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#createAnchorElement usual parameters', (t) => {
 | 
			
		||||
  const a = createAnchorElement({ document, text: 'a', url: 'b' })
 | 
			
		||||
  t.is(a.tagName, 'A')
 | 
			
		||||
  t.is(a.innerHTML, 'a')
 | 
			
		||||
  t.is(a.getAttribute('href'), 'b')
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										7
									
								
								source/front/html-creator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								source/front/html-creator.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
export function createAnchorElement({ document, text, url }) {
 | 
			
		||||
  const a = document.createElement('a')
 | 
			
		||||
  a.setAttribute('href', url)
 | 
			
		||||
  a.setAttribute('target', '_blank')
 | 
			
		||||
  a.innerHTML = text
 | 
			
		||||
  return a
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								source/front/object-hash-wrapper-test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								source/front/object-hash-wrapper-test.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
import test from 'ava'
 | 
			
		||||
import hash from './object-hash-wrapper'
 | 
			
		||||
 | 
			
		||||
test('#hash object', (t) => {
 | 
			
		||||
  t.is(hash({ foo: 'bar' }), 'a75c05bdca7d704bdfcd761913e5a4e4636e956b')
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										5
									
								
								source/front/object-hash-wrapper.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								source/front/object-hash-wrapper.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
import objectHash from 'object-hash'
 | 
			
		||||
 | 
			
		||||
export default function hash(object) {
 | 
			
		||||
  return objectHash(object)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								source/front/session-cache-test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								source/front/session-cache-test.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
import test from 'ava'
 | 
			
		||||
import SessionCache from './session-cache'
 | 
			
		||||
 | 
			
		||||
const fakeStorage = {
 | 
			
		||||
  elements: {},
 | 
			
		||||
 | 
			
		||||
  clear() {
 | 
			
		||||
    this.elements = {}
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  getItem(key) {
 | 
			
		||||
    const value = this.elements[key]
 | 
			
		||||
    if (value === undefined) return null
 | 
			
		||||
    return value
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  setItem(key, value) {
 | 
			
		||||
    this.elements[key] = value
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
test.afterEach(() => {
 | 
			
		||||
  fakeStorage.clear()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#add & #get', (t) => {
 | 
			
		||||
  SessionCache.add(fakeStorage, { a: 'b' }, { c: 'd' })
 | 
			
		||||
  t.deepEqual(SessionCache.get(fakeStorage, { a: 'b' }), { c: 'd' })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('#get no entry', (t) => {
 | 
			
		||||
  t.is(SessionCache.get(fakeStorage, { a: 'bb' }), null)
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										27
									
								
								source/front/session-cache.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								source/front/session-cache.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
import hash from './object-hash-wrapper'
 | 
			
		||||
 | 
			
		||||
const MAX_AGE_IN_MS = 120000
 | 
			
		||||
 | 
			
		||||
export default class SessionCache {
 | 
			
		||||
  static add(storage, parameters, data) {
 | 
			
		||||
    const key = hash(parameters)
 | 
			
		||||
    const timestamp = Date.now()
 | 
			
		||||
    const value = {
 | 
			
		||||
      data,
 | 
			
		||||
      timestamp,
 | 
			
		||||
    }
 | 
			
		||||
    storage.setItem(key, JSON.stringify(value))
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static get(storage, parameters) {
 | 
			
		||||
    const key = hash(parameters)
 | 
			
		||||
    const value = JSON.parse(storage.getItem(key))
 | 
			
		||||
    if (
 | 
			
		||||
      value &&
 | 
			
		||||
      value.timestamp &&
 | 
			
		||||
      value.timestamp > Date.now() - MAX_AGE_IN_MS
 | 
			
		||||
    )
 | 
			
		||||
      return value.data
 | 
			
		||||
    return null
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user