Skip to content

Commit

Permalink
Merge pull request #49 from akvo/feature/27-add-user-page-feedback
Browse files Browse the repository at this point in the history
Feature/27 add user page feedback
  • Loading branch information
dedenbangkit committed Jul 17, 2023
2 parents d4195f6 + 66dba12 commit 357b30d
Show file tree
Hide file tree
Showing 12 changed files with 81 additions and 473 deletions.
39 changes: 39 additions & 0 deletions app/__tests__/database.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,43 @@ describe('conn.tx', () => {
expect.any(Function),
);
});

test('should execute the select with no case condition', async () => {
// Mock the result set for select
const userData = [
{
name: 'Leo',
},
];
const mockSelectSql = jest.fn((query, params, successCallback) => {
successCallback(null, { rows: { length: userData.length, _array: userData } });
});
db.transaction.mockImplementation((transactionFunction) => {
transactionFunction({
executeSql: mockSelectSql,
});
});

// Define the query and parameters for select
const table = 'users';
const name = 'leo';
const where = { name };
const selectQuery = query.read(table, where, true);
const selectParams = [name];

// Execute the select transaction
const result = await conn.tx(db, selectQuery, selectParams);

// Assertions
expect(selectQuery).toEqual('SELECT * FROM users WHERE name = ? COLLATE NOCASE;');
expect(result.rows).toHaveLength(userData.length);
expect(result.rows._array).toEqual(userData);
expect(db.transaction).toHaveBeenCalled();
expect(mockSelectSql).toHaveBeenCalledWith(
selectQuery,
selectParams,
expect.any(Function),
expect.any(Function),
);
});
});
13 changes: 10 additions & 3 deletions app/src/components/LogoutButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,19 @@ const LogoutButton = () => {
<View>
<ListItem onPress={() => setVisible(true)} testID="list-item-logout">
<ListItem.Content>
<ListItem.Title>Log Out</ListItem.Title>
<ListItem.Title>Reset</ListItem.Title>
</ListItem.Content>
<Icon name="log-out-outline" type="ionicon" />
<Icon name="refresh" type="ionicon" />
</ListItem>
<Dialog testID="dialog-confirm-logout" isVisible={visible}>
{loading ? <Dialog.Loading /> : <Text>Are you sure you want to log out?</Text>}
{loading ? (
<Dialog.Loading />
) : (
<Text>
By resetting, you'll lose all saved data including users, forms and data-points. Are you
sure?
</Text>
)}
<Dialog.Actions>
<Dialog.Button onPress={handleYesPress} testID="dialog-button-yes">
Yes
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/__tests__/LogoutButton.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('LogoutButton', () => {
const logoutItem = getByTestId('list-item-logout');
expect(logoutItem).toBeDefined();

const logoutText = getByText('Log Out');
const logoutText = getByText('Reset');
expect(logoutText).toBeDefined();
});

Expand Down
10 changes: 8 additions & 2 deletions app/src/database/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@ const update = (table, where = {}, data = {}) => {
return `UPDATE ${table} SET ${fieldString} ${conditionString};`;
};

const read = (table, where = {}) => {
const read = (table, where = {}, nocase = false) => {
const conditions = Object.keys(where).map((key) => `${key} = ?`);
const conditionString = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';
let conditionString = '';
if (conditions.length) {
conditionString = `WHERE ${conditions.join(' AND ')}`;
if (nocase) {
conditionString += ' COLLATE NOCASE';
}
}
return `SELECT * FROM ${table} ${conditionString};`;
};

Expand Down
6 changes: 3 additions & 3 deletions app/src/pages/AddUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const AddUser = ({ navigation }) => {
};

const checkExistingUser = async (name) => {
const checkQuery = query.read('users', { name });
const checkQuery = query.read('users', { name }, true);
const { rows } = await conn.tx(db, checkQuery, [name]);
return rows.length;
};
Expand Down Expand Up @@ -135,7 +135,7 @@ const AddUser = ({ navigation }) => {
/>
</ListItem.Content>
</ListItem>
<ListItem>
{/* <ListItem>
<ListItem.Content>
<ListItem.Title>Password</ListItem.Title>
<Input
Expand All @@ -160,7 +160,7 @@ const AddUser = ({ navigation }) => {
testID="input-confirm-password"
/>
</ListItem.Content>
</ListItem>
</ListItem> */}

<View
style={{ display: 'flex', flexDirection: 'column', gap: 8, paddingHorizontal: 16 }}
Expand Down
15 changes: 1 addition & 14 deletions app/src/pages/AuthForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,13 @@ const AuthForm = ({ navigation }) => {
const isNetworkAvailable = UIState.useState((s) => s.online);
const [passcode, setPasscode] = React.useState(null);
const [hidden, setHidden] = React.useState(true);
const [checked, setChecked] = React.useState(false);
const [loading, setLoading] = React.useState(false);
const [error, setError] = React.useState(null);

const toggleHidden = () => setHidden(!hidden);
const goTo = (page) => navigation.navigate(page);

const disableLoginButton = React.useMemo(
() => !passcode || passcode === '' || !checked,
[passcode, checked],
);
const disableLoginButton = React.useMemo(() => !passcode || passcode === '', [passcode]);

const handleOnPressLogin = () => {
// check connection
Expand Down Expand Up @@ -116,15 +112,6 @@ const AuthForm = ({ navigation }) => {
{error}
</Text>
)}
<CheckBox
title="I accept the Terms or Conditions"
checked={checked}
onPress={() => setChecked(!checked)}
containerStyle={styles.checkbox}
textStyle={styles.text}
testID="auth-checkbox-field"
center
/>
</View>
<Button
title="primary"
Expand Down
42 changes: 15 additions & 27 deletions app/src/pages/Users.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,40 +22,28 @@ const Users = ({ navigation, route }) => {
navigation.navigate('Home');
};

const loadUsers = () => {
const loadUsers = async () => {
const selectQuery = query.read('users');
conn
.tx(db, selectQuery)
.then(({ rows }) => {
setUsers(rows._array);
setLoading(false);
})
.catch(() => {
setLoading(false);
});
const { rows } = await conn.tx(db, selectQuery);
setUsers(rows._array);
setLoading(false);
};

const handleSelectUser = async (id, name) => {
try {
const currUserQuery = query.update('users', { id: currUserID }, { active: 0 });
await conn.tx(db, currUserQuery, [currUserID]);
const currUserQuery = query.update('users', { id: currUserID }, { active: 0 });
await conn.tx(db, currUserQuery, [currUserID]);

const thisUserQuery = query.update('users', { id }, { active: 1 });
await conn.tx(db, thisUserQuery, [id]);
const thisUserQuery = query.update('users', { id }, { active: 1 });
await conn.tx(db, thisUserQuery, [id]);

UserState.update((s) => {
s.id = id;
s.name = name;
});
loadUsers();
UserState.update((s) => {
s.id = id;
s.name = name;
});
await loadUsers();

if (Platform.OS === 'android') {
ToastAndroid.show(`Switch to ${name}`, ToastAndroid.SHORT);
}
} catch {
if (Platform.OS === 'android') {
ToastAndroid.show('Unable to switch user', ToastAndroid.SHORT);
}
if (Platform.OS === 'android') {
ToastAndroid.show(`Switch to ${name}`, ToastAndroid.SHORT);
}
};

Expand Down
4 changes: 2 additions & 2 deletions app/src/pages/__tests__/AddUser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe('AddUserPage', () => {
expect(errorText).toBeDefined();
});
});

/*
test('confirm password not matched', async () => {
const { result: navigationRef } = renderHook(() => useNavigation());
const navigation = navigationRef.current;
Expand All @@ -56,7 +56,7 @@ describe('AddUserPage', () => {
const errorText = getByText('Passwords must match');
expect(errorText).toBeDefined();
});
});
}); */

test('create username correctly', async () => {
const { result: navigationRef } = renderHook(() => useNavigation());
Expand Down
12 changes: 1 addition & 11 deletions app/src/pages/__tests__/AuthForm.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,13 @@ describe('AuthFormPage', () => {

const passcodeInput = getByTestId('auth-password-field');
expect(passcodeInput).toBeDefined();
const checkbox = getByTestId('auth-checkbox-field');
expect(checkbox).toBeDefined();
const loginButton = getByTestId('auth-login-button');
expect(loginButton).toBeDefined();

fireEvent.changeText(passcodeInput, '123456');
expect(loginButton.props.accessibilityState.disabled).toBe(true);
fireEvent.press(checkbox);
expect(loginButton.props.accessibilityState.disabled).toBe(false);
fireEvent.press(loginButton);

fireEvent.press(loginButton);
expect(api.post).not.toHaveBeenCalled();
});

Expand All @@ -60,11 +56,9 @@ describe('AuthFormPage', () => {
});
});
const passcodeInput = getByTestId('auth-password-field');
const checkbox = getByTestId('auth-checkbox-field');
const loginButton = getByTestId('auth-login-button');

fireEvent.changeText(passcodeInput, '123456');
fireEvent.press(checkbox);
fireEvent.press(loginButton);

expect(api.post).toHaveBeenCalledWith('/auth', expect.any(FormData), {
Expand Down Expand Up @@ -98,11 +92,9 @@ describe('AuthFormPage', () => {
});

const passcodeInput = getByTestId('auth-password-field');
const checkbox = getByTestId('auth-checkbox-field');
const loginButton = getByTestId('auth-login-button');

fireEvent.changeText(passcodeInput, '123456');
fireEvent.press(checkbox);
fireEvent.press(loginButton);

expect(api.post).toHaveBeenCalledWith('/auth', expect.any(FormData), {
Expand Down Expand Up @@ -139,11 +131,9 @@ describe('AuthFormPage', () => {
});

const passcodeInput = getByTestId('auth-password-field');
const checkbox = getByTestId('auth-checkbox-field');
const loginButton = getByTestId('auth-login-button');

fireEvent.changeText(passcodeInput, '123456');
fireEvent.press(checkbox);
fireEvent.press(loginButton);

expect(api.post).toHaveBeenCalledWith('/auth', expect.any(FormData), {
Expand Down
Loading

0 comments on commit 357b30d

Please sign in to comment.