fix some tests

This commit is contained in:
Audric Ackermann 2020-11-25 09:14:22 +11:00
parent 51ea762bce
commit 291d4682e4
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4
15 changed files with 40 additions and 438 deletions

View File

@ -180,7 +180,12 @@ module.exports = grunt => {
tasks: ['sass'],
},
transpile: {
files: ['./ts/**/*.ts', './ts/**/*.tsx', './ts/**/**/*.tsx'],
files: [
'./ts/**/*.ts',
'./ts/**/*.tsx',
'./ts/**/**/*.tsx',
'./test/ts/**.ts',
],
tasks: ['exec:transpile'],
},
},

View File

@ -7,4 +7,5 @@ export type ConversationControllerType = {
getOrThrow: (id: string) => ConversationModel;
getOrCreateAndWait: (id: string, type: string) => Promise<ConversationModel>;
getOrCreate: (id: string, type: string) => Promise<ConversationModel>;
dangerouslyCreateAndAdd: (any) => any;
};

View File

@ -26,8 +26,8 @@
<body>
<div class='app-loading-screen'>
<div class="content session-full-logo">
<img src="images/session/brand.svg" class="session-brand-logo" />
<img src="images/session/session-text.svg" class="session-text-logo" />
<img src="images/session/brand.svg" class="session-brand-logo" />
<img src="images/session/session-text.svg" class="session-text-logo" />
</div>
</div>
<script type='text/javascript' src='js/password_start.js'></script>

View File

@ -487,8 +487,10 @@ describe('Backup', () => {
console.log('Backup test: Create models, save to db/disk');
const message = await upgradeMessageSchema(messageWithAttachments);
console.log({ message });
await message.commit();
await window.Signal.Data.saveMessage(message, {
Message: Whisper.Message,
forceSave: true,
});
const conversation = {
active_at: 1524185933350,

View File

@ -1,11 +1,11 @@
/* global Whisper */
Whisper.Fixtures = () => {
const VERA_ID = '+13016886524'; // nsa
const NESTOR_ID = '+17034820623'; // cia
const MASHA_ID = '+441242221491'; // gchq
const FRED_ID = '+14155537400'; // fbi sf
const MICHEL_ID = '+12024561111'; // twh
const VERA_ID = '0501cd123456789abcdef05123456789abcdef05123456789abcdef05123456789'; // nsa
const NESTOR_ID = '0502cd123456789abcdef05123456789abcdef05123456789abcdef05123456789'; // cia
const MASHA_ID = '0503cd123456789abcdef05123456789abcdef05123456789abcdef05123456789'; // gchq
const FRED_ID = '0504cd123456789abcdef05123456789abcdef05123456789abcdef05123456789'; // fbi sf
const MICHEL_ID = '0505cd123456789abcdef05123456789abcdef05123456789abcdef05123456789'; // twh
const now = Date.now();
const conversationCollection = new Whisper.ConversationCollection([
@ -172,7 +172,7 @@ Whisper.Fixtures = () => {
type: 'group',
active_at: now - 100000,
timestamp: now - 100000,
id: 'group1',
id: '05abcd123456789abcdef05123456789abcdef05123456789abcdef05123456789',
lastMessage: 'See you all there!',
members: [MICHEL_ID, FRED_ID, NESTOR_ID],
});

View File

@ -9,7 +9,7 @@ describe('Fixtures', () => {
await clearDatabase();
await textsecure.storage.user.setNumberAndDeviceId(
'+17015552000',
'05123456789abcdef05123456789abcdef05123456789abcdef05123456789abcd',
2,
'testDevice'
);
@ -27,12 +27,10 @@ describe('Fixtures', () => {
await ConversationController.load();
let view = new Whisper.InboxView({ window });
view.onEmpty();
view.$el.prependTo($('#render-light-theme'));
view = new Whisper.InboxView({ window });
view.$el.removeClass('light-theme').addClass('dark-theme');
view.onEmpty();
view.$el.prependTo($('#render-dark-theme'));
});
});

View File

@ -19,8 +19,8 @@
<script type="text/x-tmpl-mustache" id="app-loading-screen">
<div class="content session-full-logo">
<img src="images/session/brand.svg" class="session-brand-logo" />
<img src="images/session/session-text.svg" class="session-text-logo" />
<img src="../images/session/brand.svg" class="session-brand-logo" />
<img src="../images/session/session-text.svg" class="session-text-logo" />
</div>
</script>

View File

@ -1,79 +0,0 @@
/* global ConversationController, libsignal, SignalProtocolStore, Whisper */
describe('KeyChangeListener', () => {
const phoneNumberWithKeyChange = '+13016886524'; // nsa
const address = new libsignal.SignalProtocolAddress(
phoneNumberWithKeyChange,
1
);
const oldKey = libsignal.crypto.getRandomBytes(33);
const newKey = libsignal.crypto.getRandomBytes(33);
let store;
beforeEach(async () => {
store = new SignalProtocolStore();
await store.hydrateCaches();
Whisper.KeyChangeListener.init(store);
return store.saveIdentity(address.toString(), oldKey);
});
afterEach(() => {
return store.removeIdentityKey(phoneNumberWithKeyChange);
});
describe('When we have a conversation with this contact', () => {
let convo;
before(async () => {
convo = ConversationController.dangerouslyCreateAndAdd({
id: phoneNumberWithKeyChange,
type: 'private',
});
await window.Signal.Data.saveConversation(convo.attributes, {
Conversation: Whisper.Conversation,
});
});
after(async () => {
await convo.destroyMessages();
await window.Signal.Data.saveConversation(convo.id);
});
it('generates a key change notice in the private conversation with this contact', done => {
convo.once('newmessage', async () => {
await convo.fetchMessages();
const message = convo.messageCollection.at(0);
assert.strictEqual(message.get('type'), 'keychange');
done();
});
store.saveIdentity(address.toString(), newKey);
});
});
describe('When we have a group with this contact', () => {
let convo;
before(async () => {
convo = ConversationController.dangerouslyCreateAndAdd({
id: 'groupId',
type: 'group',
members: [phoneNumberWithKeyChange],
});
await window.Signal.Data.saveConversation(convo.attributes, {
Conversation: Whisper.Conversation,
});
});
after(async () => {
await convo.destroyMessages();
await window.Signal.Data.saveConversation(convo.id);
});
it('generates a key change notice in the group conversation with this contact', done => {
convo.once('newmessage', async () => {
await convo.fetchMessages();
const message = convo.messageCollection.at(0);
assert.strictEqual(message.get('type'), 'keychange');
done();
});
store.saveIdentity(address.toString(), newKey);
});
});
});

View File

@ -1,326 +0,0 @@
const { assert } = require('chai');
const {
findLinks,
getTitleMetaTag,
getImageMetaTag,
isLinkInWhitelist,
isLinkSneaky,
} = require('../../js/modules/link_previews');
describe('Link previews', () => {
describe('#isLinkInWhitelist', () => {
it('returns true for valid links', () => {
assert.strictEqual(isLinkInWhitelist('https://youtube.com/blah'), true);
assert.strictEqual(
isLinkInWhitelist('https://www.youtube.com/blah'),
true
);
assert.strictEqual(isLinkInWhitelist('https://m.youtube.com/blah'), true);
assert.strictEqual(isLinkInWhitelist('https://youtu.be/blah'), true);
assert.strictEqual(isLinkInWhitelist('https://reddit.com/blah'), true);
assert.strictEqual(
isLinkInWhitelist('https://www.reddit.com/blah'),
true
);
assert.strictEqual(isLinkInWhitelist('https://m.reddit.com/blah'), true);
assert.strictEqual(isLinkInWhitelist('https://imgur.com/blah'), true);
assert.strictEqual(isLinkInWhitelist('https://www.imgur.com/blah'), true);
assert.strictEqual(isLinkInWhitelist('https://m.imgur.com/blah'), true);
assert.strictEqual(isLinkInWhitelist('https://instagram.com/blah'), true);
assert.strictEqual(
isLinkInWhitelist('https://www.instagram.com/blah'),
true
);
assert.strictEqual(
isLinkInWhitelist('https://m.instagram.com/blah'),
true
);
});
it('returns false for subdomains', () => {
assert.strictEqual(
isLinkInWhitelist('https://any.subdomain.youtube.com/blah'),
false
);
assert.strictEqual(
isLinkInWhitelist('https://any.subdomain.instagram.com/blah'),
false
);
});
it('returns false for http links', () => {
assert.strictEqual(isLinkInWhitelist('http://instagram.com/blah'), false);
assert.strictEqual(isLinkInWhitelist('http://youtube.com/blah'), false);
});
it('returns false for links with no protocol', () => {
assert.strictEqual(isLinkInWhitelist('instagram.com/blah'), false);
assert.strictEqual(isLinkInWhitelist('youtube.com/blah'), false);
});
it('returns false for link to root path', () => {
assert.strictEqual(isLinkInWhitelist('https://instagram.com'), false);
assert.strictEqual(isLinkInWhitelist('https://youtube.com'), false);
assert.strictEqual(isLinkInWhitelist('https://instagram.com/'), false);
assert.strictEqual(isLinkInWhitelist('https://youtube.com/'), false);
});
it('returns false for other well-known sites', () => {
assert.strictEqual(isLinkInWhitelist('https://facebook.com/blah'), false);
assert.strictEqual(isLinkInWhitelist('https://twitter.com/blah'), false);
});
it('returns false for links that look like our target links', () => {
assert.strictEqual(
isLinkInWhitelist('https://evil.site.com/.instagram.com/blah'),
false
);
assert.strictEqual(
isLinkInWhitelist('https://evil.site.com/.instagram.com/blah'),
false
);
assert.strictEqual(
isLinkInWhitelist('https://sinstagram.com/blah'),
false
);
});
});
describe('#_getMetaTag', () => {
it('returns html-decoded tag contents from Youtube', () => {
const youtube = `
<meta property="og:site_name" content="YouTube">
<meta property="og:url" content="https://www.youtube.com/watch?v=tP-Ipsat90c">
<meta property="og:type" content="video.other">
<meta property="og:title" content="Randomness is Random - Numberphile">
<meta property="og:image" content="https://i.ytimg.com/vi/tP-Ipsat90c/maxresdefault.jpg">
`;
assert.strictEqual(
'Randomness is Random - Numberphile',
getTitleMetaTag(youtube)
);
assert.strictEqual(
'https://i.ytimg.com/vi/tP-Ipsat90c/maxresdefault.jpg',
getImageMetaTag(youtube)
);
});
it('returns html-decoded tag contents from Instagram', () => {
const instagram = `
<meta property="og:site_name" content="Instagram" />
<meta property="og:url" content="https://www.instagram.com/p/BrgpsUjF9Jo/" />
<meta property="og:type" content="instapp:photo" />
<meta property="og:title" content="Walter &#34;MFPallytime&#34; on Instagram: “Lol gg”" />
<meta property="og:description" content="632 Likes, 56 Comments - Walter &#34;MFPallytime&#34; (@mfpallytime) on Instagram: “Lol gg ”" />
<meta property="og:image" content="https://scontent-lax3-1.cdninstagram.com/vp/1c69aa381c2201720c29a6c28de42ffd/5CD49B5B/t51.2885-15/e35/47690175_2275988962411653_1145978227188801192_n.jpg?_nc_ht=scontent-lax3-1.cdninstagram.com" />
`;
assert.strictEqual(
'Walter "MFPallytime" on Instagram: “Lol gg”',
getTitleMetaTag(instagram)
);
assert.strictEqual(
'https://scontent-lax3-1.cdninstagram.com/vp/1c69aa381c2201720c29a6c28de42ffd/5CD49B5B/t51.2885-15/e35/47690175_2275988962411653_1145978227188801192_n.jpg?_nc_ht=scontent-lax3-1.cdninstagram.com',
getImageMetaTag(instagram)
);
});
it('returns html-decoded tag contents from Imgur', () => {
const imgur = `
<meta property="og:site_name" content="Imgur">
<meta property="og:url" content="https://imgur.com/gallery/KFCL8fm">
<meta property="og:type" content="article">
<meta property="og:title" content="&nbsp;">
<meta property="og:description" content="13246 views and 482 votes on Imgur">
<meta property="og:image" content="https://i.imgur.com/Y3wjlwY.jpg?fb">
<meta property="og:image:width" content="600">
<meta property="og:image:height" content="315">
`;
assert.strictEqual('', getTitleMetaTag(imgur));
assert.strictEqual(
'https://i.imgur.com/Y3wjlwY.jpg?fb',
getImageMetaTag(imgur)
);
});
it('returns html-decoded tag contents from Giphy', () => {
const giphy = `
<meta property="og:site_name" content="GIPHY">
<meta property="og:url" content="https://media.giphy.com/media/3o7qE8mq5bT9FQj7j2/giphy.gif">
<meta property="og:type" content="video.other">
<meta property="og:title" content="I Cant Hear You Kobe Bryant GIF - Find & Share on GIPHY">
<meta property="og:description" content="Discover &amp; share this Kobe GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.">
<meta property="og:image" content="https://media.giphy.com/media/3o7qE8mq5bT9FQj7j2/giphy.gif">
<meta property="og:image:width" content="480">
<meta property="og:image:height" content="262">
`;
assert.strictEqual(
'I Cant Hear You Kobe Bryant GIF - Find & Share on GIPHY',
getTitleMetaTag(giphy)
);
assert.strictEqual(
'https://media.giphy.com/media/3o7qE8mq5bT9FQj7j2/giphy.gif',
getImageMetaTag(giphy)
);
});
it('returns html-decoded tag contents from Tenor', () => {
const tenor = `
<meta class="dynamic" property="og:site_name" content="Tenor" >
<meta class="dynamic" property="og:url" content="https://media1.tenor.com/images/3772949a5b042e626d259f313fd1e9b8/tenor.gif?itemid=14834517">
<meta class="dynamic" property="og:type" content="video.other">
<meta class="dynamic" property="og:title" content="Hopping Jumping GIF - Hopping Jumping Bird - Discover & Share GIFs">
<meta class="dynamic" property="og:description" content="Click to view the GIF">
<meta class="dynamic" property="og:image" content="https://media1.tenor.com/images/3772949a5b042e626d259f313fd1e9b8/tenor.gif?itemid=14834517">
<meta class="dynamic" property="og:image:width" content="498">
<meta class="dynamic" property="og:image:height" content="435">
`;
assert.strictEqual(
'Hopping Jumping GIF - Hopping Jumping Bird - Discover & Share GIFs',
getTitleMetaTag(tenor)
);
assert.strictEqual(
'https://media1.tenor.com/images/3772949a5b042e626d259f313fd1e9b8/tenor.gif?itemid=14834517',
getImageMetaTag(tenor)
);
});
it('returns only the first tag', () => {
const html = `
<meta property="og:title" content="First&nbsp;Second&nbsp;Third"><meta property="og:title" content="Fourth&nbsp;Fifth&nbsp;Sixth">
`;
assert.strictEqual('First Second Third', getTitleMetaTag(html));
});
it('handles a newline in attribute value', () => {
const html = `
<meta property="og:title" content="First thing\r\nSecond thing\nThird thing">
`;
assert.strictEqual(
'First thing\r\nSecond thing\nThird thing',
getTitleMetaTag(html)
);
});
it('converts image url protocol http to https', () => {
const html = `
<meta property="og:image" content="http://giphygifs.s3.amazonaws.com/media/APcFiiTrG0x2/200.gif">
`;
assert.strictEqual(
'https://giphygifs.s3.amazonaws.com/media/APcFiiTrG0x2/200.gif',
getImageMetaTag(html)
);
});
});
describe('#findLinks', () => {
it('returns all links if no caretLocation is provided', () => {
const text =
'Check out this link: https://github.com/signalapp/Signal-Desktop\nAnd this one too: https://github.com/signalapp/Signal-Android';
const expected = [
'https://github.com/signalapp/Signal-Desktop',
'https://github.com/signalapp/Signal-Android',
];
const actual = findLinks(text);
assert.deepEqual(expected, actual);
});
it('includes all links if cursor is not in a link', () => {
const text =
'Check out this link: https://github.com/signalapp/Signal-Desktop\nAnd this one too: https://github.com/signalapp/Signal-Android';
const caretLocation = 10;
const expected = [
'https://github.com/signalapp/Signal-Desktop',
'https://github.com/signalapp/Signal-Android',
];
const actual = findLinks(text, caretLocation);
assert.deepEqual(expected, actual);
});
it('excludes a link not at the end if the caret is inside of it', () => {
const text =
'Check out this link: https://github.com/signalapp/Signal-Desktop\nAnd this one too: https://github.com/signalapp/Signal-Android';
const caretLocation = 30;
const expected = ['https://github.com/signalapp/Signal-Android'];
const actual = findLinks(text, caretLocation);
assert.deepEqual(expected, actual);
});
it('excludes a link not at the end if the caret is at its end', () => {
const text =
'Check out this link: https://github.com/signalapp/Signal-Desktop\nAnd this one too: https://github.com/signalapp/Signal-Android';
const caretLocation = 64;
const expected = ['https://github.com/signalapp/Signal-Android'];
const actual = findLinks(text, caretLocation);
assert.deepEqual(expected, actual);
});
it('excludes a link at the end of the caret is inside of it', () => {
const text =
'Check out this link: https://github.com/signalapp/Signal-Desktop\nAnd this one too: https://github.com/signalapp/Signal-Android';
const caretLocation = 100;
const expected = ['https://github.com/signalapp/Signal-Desktop'];
const actual = findLinks(text, caretLocation);
assert.deepEqual(expected, actual);
});
it('includes link at the end if cursor is at its end', () => {
const text =
'Check out this link: https://github.com/signalapp/Signal-Desktop\nAnd this one too: https://github.com/signalapp/Signal-Android';
const caretLocation = text.length;
const expected = [
'https://github.com/signalapp/Signal-Desktop',
'https://github.com/signalapp/Signal-Android',
];
const actual = findLinks(text, caretLocation);
assert.deepEqual(expected, actual);
});
});
describe('#isLinkSneaky', () => {
it('returns false for all-latin domain', () => {
const link = 'https://www.amazon.com';
const actual = isLinkSneaky(link);
assert.strictEqual(actual, false);
});
it('returns true for Latin + Cyrillic domain', () => {
const link = 'https://www.aмazon.com';
const actual = isLinkSneaky(link);
assert.strictEqual(actual, true);
});
it('returns true for Latin + Greek domain', () => {
const link = 'https://www.αpple.com';
const actual = isLinkSneaky(link);
assert.strictEqual(actual, true);
});
it('returns true for Latin + High Greek domain', () => {
const link = `https://www.apple${String.fromCodePoint(0x101a0)}.com`;
const actual = isLinkSneaky(link);
assert.strictEqual(actual, true);
});
});
});

View File

@ -50,7 +50,12 @@ export class ContactListItem extends React.Component<Props> {
const profileElement =
!isMe && profileName && !name ? (
<span className="module-contact-list-item__text__profile-name">
~<Emojify text={profileName} i18n={i18n} />
~
<Emojify
text={profileName}
i18n={i18n}
key={`emojify-list-item-${phoneNumber}`}
/>
</span>
) : null;

View File

@ -4,7 +4,6 @@ import { Avatar } from '../Avatar';
import { LocalizerType } from '../../types/Util';
import {
SessionIcon,
SessionIconButton,
SessionIconSize,
SessionIconType,
@ -89,7 +88,6 @@ interface Props {
onAvatarClick?: (userPubKey: string) => void;
onUpdateGroupName: () => void;
i18n: LocalizerType;
memberAvatars?: Array<ConversationAvatar>; // this is added by usingClosedConversationDetails
}
@ -121,7 +119,6 @@ class ConversationHeader extends React.Component<Props> {
public renderTitle() {
const {
phoneNumber,
i18n,
profileName,
isGroup,
isPublic,
@ -132,6 +129,7 @@ class ConversationHeader extends React.Component<Props> {
isKickedFromGroup,
name,
} = this.props;
const { i18n } = window;
if (isMe) {
return (
@ -232,12 +230,9 @@ class ConversationHeader extends React.Component<Props> {
}
public renderSelectionOverlay() {
const {
onDeleteSelectedMessages,
onCloseOverlay,
isPublic,
i18n,
} = this.props;
const { onDeleteSelectedMessages, onCloseOverlay, isPublic } = this.props;
const { i18n } = window;
const isServerDeletable = isPublic;
const deleteMessageButtonText = i18n(
isServerDeletable ? 'deleteForEveryone' : 'delete'
@ -266,7 +261,7 @@ class ConversationHeader extends React.Component<Props> {
}
public render() {
const { id, isKickedFromGroup, selectionMode } = this.props;
const { isKickedFromGroup, selectionMode } = this.props;
const triggerId = 'conversation-header';
return (

View File

@ -86,9 +86,9 @@ export class Emojify extends React.Component<Props> {
const emojiText = match[0] ?? match[1];
results.push(
<span style={style}>
<span style={style} key={count++}>
<Twemoji
key={count++}
key={count}
text={emojiText}
options={
{

View File

@ -72,8 +72,9 @@ class ActionsPanelPrivate extends React.Component<Props> {
if (type === SectionType.Profile) {
const ourPrimary = window.storage.get('primaryDevicePubKey');
const conversation = window.ConversationController.getOrThrow(ourPrimary);
const profile = conversation.getLokiProfile();
const conversation = window.ConversationController.get(ourPrimary);
const profile = conversation?.getLokiProfile();
const userName = (profile && profile.displayName) || ourPrimary;
return (
<Avatar
@ -136,7 +137,7 @@ class ActionsPanelPrivate extends React.Component<Props> {
<div className="module-left-pane__sections-container">
<this.Section
type={SectionType.Profile}
avatarPath={this.props.ourPrimaryConversation.avatarPath}
avatarPath={this.props.ourPrimaryConversation?.avatarPath}
isSelected={isProfilePageSelected}
onSelect={this.handleSectionSelect}
/>

View File

@ -412,7 +412,6 @@ export class SessionConversation extends React.Component<Props, State> {
const members = conversation.get('members') || [];
const headerProps = {
i18n: window.i18n,
id: conversation.id,
name: conversation.getName(),
phoneNumber: conversation.getNumber(),

1
ts/window.d.ts vendored
View File

@ -26,6 +26,7 @@ declare global {
interface Window {
CONSTANTS: any;
ConversationController: ConversationControllerType;
SignalProtocolStore: any;
Events: any;
Lodash: any;
LokiAppDotNetServerAPI: any;