Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite angular service - input-matcher #1061

Merged
merged 21 commits into from
Nov 10, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e945325
Rewrite input-matcher to typescript (not done)
jiji14 Oct 5, 2023
9d83cc1
delete old angular service
jiji14 Oct 12, 2023
bc74d12
add new input-matcher service
jiji14 Oct 12, 2023
eb0d63e
call input matcher functions from the new input-matcher service
jiji14 Oct 12, 2023
9c518f6
add input-matcher unit test (not done)
jiji14 Oct 12, 2023
d9936f1
delete old input-matcher angular service
jiji14 Oct 13, 2023
631de70
Add getNotDeletedCandidates input & output type
jiji14 Oct 13, 2023
7148ac6
remove input-matcher.js file
jiji14 Oct 13, 2023
16673e8
Done with input-matcher.test
jiji14 Oct 13, 2023
f891227
Merge branch 'rewrite-input-matcher' into input-matcher-rewrite
jiji14 Oct 13, 2023
95d4f64
Merge branch 'service_rewrite_2023' into input-matcher-rewrite
JGreenlee Oct 16, 2023
b8ec27d
add comments for test inputs
jiji14 Oct 16, 2023
b43b6a0
remane input-matcher to inputMatcher (follow camelCase rule)
jiji14 Oct 17, 2023
235c088
Merge branch 'input-matcher-rewrite' of https://github.com/jiji14/e-m…
jiji14 Oct 17, 2023
ffcc871
move trip related types to 'dairyTypes' file in 'types' directory
jiji14 Oct 17, 2023
1d5f1d5
Merge branch 'service_rewrite_2023' of https://github.com/e-mission/e…
JGreenlee Oct 25, 2023
b9ecdb9
Merge branch 'service_rewrite_2023' of https://github.com/e-mission/e…
JGreenlee Nov 1, 2023
58c6ce2
Merge branch 'service_rewrite_2023' into input-matcher-rewrite
jiji14 Nov 2, 2023
f490125
Merge remote-tracking branch 'upstream/service_rewrite_2023' into inp…
jiji14 Nov 2, 2023
b4bc7ab
Run prettier
jiji14 Nov 2, 2023
f2a8db6
Merge remote-tracking branch 'upstream/service_rewrite_2023' into inp…
jiji14 Nov 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
249 changes: 249 additions & 0 deletions www/__tests__/input-matcher.test.ts
shankari marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
import {
TlEntry,
UserInputForTrip,
fmtTs,
printUserInput,
validUserInputForDraftTrip,
validUserInputForTimelineEntry,
getNotDeletedCandidates,
getUserInputForTrip,
getAdditionsForTimelineEntry,
getUniqueEntries
} from '../js/survey/input-matcher';

describe('input-matcher', () => {
let userTrip: UserInputForTrip;
let trip: TlEntry;

beforeEach(() => {
// create valid userTrip and trip object before each test case.
userTrip = {
data: {
end_ts: 1437604764,
start_ts: 1437601247,
label: 'FOO',
status: 'ACTIVE'
},
shankari marked this conversation as resolved.
Show resolved Hide resolved
metadata: {
time_zone: 'America/Los_Angeles',
plugin: 'none',
write_ts: 1695921991,
platform: 'ios',
read_ts: 0,
key: 'manual/mode_confirm'
},
key: 'manual/place'
}
trip = {
key: 'FOO',
origin_key: 'FOO',
start_ts: 1437601000,
end_ts: 1437605000,
enter_ts: 1437605000,
exit_ts: 1437605000,
duration: 100,
getNextEntry: jest.fn()
}

// mock Logger
window['Logger'] = { log: console.log };
});

it('tests fmtTs with valid input', () => {
const pstTime = fmtTs(1437601247.8459613, 'America/Los_Angeles');
const estTime = fmtTs(1437601247.8459613, 'America/New_York');

// Check if it contains correct year-mm-dd hr:mm
expect(pstTime).toContain('2015-07-22T14:40');
expect(estTime).toContain('2015-07-22T17:40');
});

it('tests fmtTs with invalid input', () => {
const formattedTime = fmtTs(0, '');
expect(formattedTime).toBeFalsy();
});

it('tests printUserInput prints the trip log correctly', () => {
const userTripLog = printUserInput(userTrip);
expect(userTripLog).toContain('1437604764');
expect(userTripLog).toContain('1437601247');
expect(userTripLog).toContain('FOO');
});

it('tests validUserInputForDraftTrip with valid trip input', () => {
const validTrp = {
end_ts: 1437604764,
start_ts: 1437601247
}
const validUserInput = validUserInputForDraftTrip(validTrp, userTrip, false);
expect(validUserInput).toBeTruthy();
});

it('tests validUserInputForDraftTrip with invalid trip input', () => {
const invalidTrip = {
end_ts: 0,
start_ts: 0
}
const invalidUserInput = validUserInputForDraftTrip(invalidTrip, userTrip, false);
expect(invalidUserInput).toBeFalsy();
});

it('tests validUserInputForTimelineEntry with valid trip object', () => {
// we need valid key and origin_key for validUserInputForTimelineEntry test
trip['key'] = 'analysis/confirmed_place';
trip['origin_key'] = 'analysis/confirmed_place';
const validTimelineEntry = validUserInputForTimelineEntry(trip, userTrip, false);
expect(validTimelineEntry).toBeTruthy();
});

it('tests validUserInputForTimelineEntry with tlEntry with invalid key and origin_key', () => {
const invalidTlEntry = trip;
const invalidTimelineEntry = validUserInputForTimelineEntry(invalidTlEntry, userTrip, false);
expect(invalidTimelineEntry).toBeFalsy();
});

it('tests validUserInputForTimelineEntry with tlEntry with invalie start & end time', () => {
const invalidTlEntry: TlEntry = {
key: 'analysis/confirmed_place',
origin_key: 'analysis/confirmed_place',
start_ts: 1,
end_ts: 1,
enter_ts: 1,
exit_ts: 1,
duration: 1,
getNextEntry: jest.fn()
}
const invalidTimelineEntry = validUserInputForTimelineEntry(invalidTlEntry, userTrip, false);
expect(invalidTimelineEntry).toBeFalsy();
});

it('tests getNotDeletedCandidates called with 0 candidates', () => {
jest.spyOn(console, 'log');
const candidates = getNotDeletedCandidates([]);

// check if the log printed collectly with
expect(console.log).toHaveBeenCalledWith('getNotDeletedCandidates called with 0 candidates');
expect(candidates).toStrictEqual([]);

});

it('tests getNotDeletedCandidates called with multiple candidates', () => {
const activeTrip = userTrip;
const deletedTrip = {
data: {
end_ts: 1437604764,
start_ts: 1437601247,
label: 'FOO',
status: 'DELETED',
match_id: 'FOO'
},
metadata: {
time_zone: 'America/Los_Angeles',
plugin: 'none',
write_ts: 1695921991,
platform: 'ios',
read_ts: 0,
key: 'manual/mode_confirm'
},
key: 'manual/place'
}
const candidates = [ activeTrip, deletedTrip ];
const validCandidates = getNotDeletedCandidates(candidates);

// check if the result has only 'ACTIVE' data
expect(validCandidates).toHaveLength(1);
expect(validCandidates[0]).toMatchObject(userTrip);

});

it('tests getUserInputForTrip with valid userInputList', () => {
const userInputWriteFirst = {
data: {
end_ts: 1437607732,
label: 'bus',
start_ts: 1437606026
},
metadata: {
time_zone: 'America/Los_Angeles',
plugin: 'none',
write_ts: 1695830232,
platform: 'ios',
read_ts: 0,
key:'manual/mode_confirm',
type:'message'
}
}
const userInputWriteSecond = {
data: {
end_ts: 1437598393,
label: 'e-bike',
start_ts: 1437596745
},
metadata: {
time_zone: 'America/Los_Angeles',
plugin: 'none',
write_ts: 1695838268,
platform: 'ios',
read_ts: 0,
key:'manual/mode_confirm',
type:'message'
}
}
const userInputWriteThird = {
data: {
end_ts: 1437604764,
label: 'e-bike',
start_ts: 1437601247
},
metadata: {
time_zone: 'America/Los_Angeles',
plugin: 'none',
write_ts: 1695921991,
platform: 'ios',
read_ts: 0,
key:'manual/mode_confirm',
type:'message'
}
}

// make the linst unsorted and then check if userInputWriteThird(latest one) is return output
const userInputList = [userInputWriteSecond, userInputWriteThird, userInputWriteFirst];
const mostRecentEntry = getUserInputForTrip(trip, {}, userInputList);
expect(mostRecentEntry).toMatchObject(userInputWriteThird);
});

it('tests getUserInputForTrip with invalid userInputList', () => {
const userInputList = undefined;
const mostRecentEntry = getUserInputForTrip(trip, {}, userInputList);
expect(mostRecentEntry).toBe(undefined);
});

it('tests getAdditionsForTimelineEntry with valid additionsList', () => {
const additionsList = new Array(5).fill(userTrip);
trip['key'] = 'analysis/confirmed_place';
trip['origin_key'] = 'analysis/confirmed_place';

// check if the result keep the all valid userTrip items
const matchingAdditions = getAdditionsForTimelineEntry(trip, additionsList);
expect(matchingAdditions).toHaveLength(5);
});

it('tests getAdditionsForTimelineEntry with invalid additionsList', () => {
const additionsList = undefined;
const matchingAdditions = getAdditionsForTimelineEntry(trip, additionsList);
expect(matchingAdditions).toMatchObject([]);
});

it('tests getUniqueEntries with valid combinedList', () => {
const combinedList = new Array(5).fill(userTrip);

// check if the result keeps only unique userTrip items
const uniqueEntires = getUniqueEntries(combinedList);
expect(uniqueEntires).toHaveLength(1);
});

it('tests getUniqueEntries with empty combinedList', () => {
const uniqueEntires = getUniqueEntries([]);
expect(uniqueEntires).toMatchObject([]);
});
})
1 change: 0 additions & 1 deletion www/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import './js/controllers.js';
import './js/services.js';
import './js/i18n-utils.js';
import './js/main.js';
import './js/survey/input-matcher.js';
import './js/survey/multilabel/infinite_scroll_filters.js';
import './js/survey/multilabel/multi-label-ui.js';
import './js/diary.js';
Expand Down
10 changes: 5 additions & 5 deletions www/js/survey/enketo/enketo-add-note-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
*/

import angular from 'angular';
import { getAdditionsForTimelineEntry, getUniqueEntries } from '../input-matcher';

angular.module('emission.survey.enketo.add-note-button',
['emission.services',
'emission.survey.enketo.answer',
'emission.survey.inputmatcher'])
.factory("EnketoNotesButtonService", function(InputMatcher, EnketoSurveyAnswer, Logger, $timeout) {
'emission.survey.enketo.answer'])
.factory("EnketoNotesButtonService", function(EnketoSurveyAnswer, Logger, $timeout) {
var enbs = {};
console.log("Creating EnketoNotesButtonService");
enbs.SINGLE_KEY="NOTES";
Expand Down Expand Up @@ -76,9 +76,9 @@ angular.module('emission.survey.enketo.add-note-button',
// be re-matching entries that have already been matched on the server
// but the number of matched entries is likely to be small, so we can live
// with the performance for now
const unprocessedAdditions = InputMatcher.getAdditionsForTimelineEntry(timelineEntry, inputList);
const unprocessedAdditions = getAdditionsForTimelineEntry(timelineEntry, inputList);
const combinedPotentialAdditionList = timelineEntry.additions.concat(unprocessedAdditions);
const dedupedList = InputMatcher.getUniqueEntries(combinedPotentialAdditionList);
const dedupedList = getUniqueEntries(combinedPotentialAdditionList);
Logger.log("After combining unprocessed ("+unprocessedAdditions.length+
") with server ("+timelineEntry.additions.length+
") for a combined ("+combinedPotentialAdditionList.length+
Expand Down
9 changes: 4 additions & 5 deletions www/js/survey/enketo/enketo-trip-button.js
shankari marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
*/

import angular from 'angular';
import { getUserInputForTrip } from '../input-matcher';

angular.module('emission.survey.enketo.trip.button',
['emission.survey.enketo.answer',
'emission.survey.inputmatcher'])
.factory("EnketoTripButtonService", function(InputMatcher, EnketoSurveyAnswer, Logger, $timeout) {
['emission.survey.enketo.answer'])
.factory("EnketoTripButtonService", function(EnketoSurveyAnswer, Logger, $timeout) {
var etbs = {};
console.log("Creating EnketoTripButtonService");
etbs.key = "manual/trip_user_input";
Expand Down Expand Up @@ -61,8 +61,7 @@ angular.module('emission.survey.enketo.trip.button',
*/
etbs.populateManualInputs = function (trip, nextTrip, inputType, inputList) {
// Check unprocessed labels first since they are more recent
const unprocessedLabelEntry = InputMatcher.getUserInputForTrip(trip, nextTrip,
inputList);
const unprocessedLabelEntry = getUserInputForTrip(trip, nextTrip,inputList);
var userInputEntry = unprocessedLabelEntry;
if (!angular.isDefined(userInputEntry)) {
userInputEntry = trip.user_input?.[etbs.inputType2retKey(inputType)];
Expand Down
Loading