Project

General

Profile

Download (4.44 KB) Statistics
| Branch: | Tag: | Revision:

haketilo / test / unit / test_indexeddb.py @ 3a90084e

1
# SPDX-License-Identifier: CC0-1.0
2

    
3
"""
4
Haketilo unit tests - IndexedDB access
5
"""
6

    
7
# This file is part of Haketilo
8
#
9
# Copyright (C) 2021, Wojtek Kosior <koszko@koszko.org>
10
#
11
# This program is free software: you can redistribute it and/or modify
12
# it under the terms of the CC0 1.0 Universal License as published by
13
# the Creative Commons Corporation.
14
#
15
# This program is distributed in the hope that it will be useful,
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
# CC0 1.0 Universal License for more details.
19

    
20
import pytest
21
from hashlib import sha256
22

    
23
from ..script_loader import load_script
24

    
25
@pytest.fixture(scope="session")
26
def indexeddb_code():
27
    yield load_script('common/indexeddb.js', ['common'])
28

    
29
def sample_file(contents):
30
    return {
31
        'sha256': sha256(contents.encode()).digest().hex(),
32
        contents: contents
33
    }
34

    
35
sample_files = {
36
    'report.spdx':              sample_file('<!-- dummy report -->'),
37
    'LICENSES/somelicense.txt': sample_file('Permission is granted...'),
38
    'hello.js':                 sample_file('console.log("hello!");\n'),
39
    'bye.js':                   sample_file('console.log("bye!");\n'),
40
    'README.md':                sample_file('# Python Frobnicator\n...')
41
}
42

    
43
sample_files_sha256 = \
44
    dict([[file['sha256'], file] for file in sample_files.values()])
45

    
46
def file_ref(file_name):
47
    return {'file': file_name, 'sha256': sample_files[file_name]['sha256']}
48

    
49
def test_save_item(execute_in_page, indexeddb_code):
50
    """
51
    indexeddb.js facilitates operating on Haketilo's internal database.
52
    Verify database operations work properly.
53
    """
54
    execute_in_page(indexeddb_code, page='https://gotmyowndoma.in')
55
    # Don't use Haketilo's default initial data.
56
    execute_in_page(
57
        '''{
58
        const _get_db = haketilodb.get;
59
        get_db = () => _get_db({});
60
        haketilodb.get = get_db;
61
        }'''
62
    )
63

    
64
    # Start with no database.
65
    execute_in_page(
66
        '''{
67
        async function delete_db() {
68
            let resolve;
69
            const result = new Promise(_resolve => resolve = _resolve);
70
            const request = indexedDB.deleteDatabase("haketilo");
71
            [request.onsuccess, request.onerror] = [resolve, resolve];
72
            await result;
73
        }
74

    
75
        returnval(delete_db());
76
        }'''
77
    )
78

    
79
    # Facilitate retrieving all IndexedDB contents.
80
    execute_in_page(
81
        '''
82
        async function get_database_contents(promise=Promise.resolve())
83
        {
84
            if (promise)
85
                await promise;
86

    
87
            const db = await haketilodb.get();
88

    
89
            const transaction = db.transaction(db.objectStoreNames);
90
            const store_names_reqs = [...db.objectStoreNames]
91
                .map(sn => [sn, transaction.objectStore(sn).getAll()])
92

    
93
            const promises = store_names_reqs
94
                .map(([_, req]) => wait_request(req));
95
            await Promise.all(promises);
96

    
97
            const result = {};
98
            store_names_reqs.forEach(([sn, req]) => result[sn] = req.result);
99
            return result;
100
        }
101
        ''')
102

    
103
    # Sample resource definition. It'd normally contain more fields but here
104
    # we use a simplified version.
105
    sample_item = {
106
        'source_copyright': [
107
            file_ref('report.spdx'),
108
            file_ref('LICENSES/somelicense.txt')
109
        ],
110
        'type': 'resource',
111
        'identifier': 'helloapple',
112
        'scripts': [file_ref('hello.js'), file_ref('bye.js')],
113
        'type': 'resource'
114
    }
115
    next(iter(sample_item['source_copyright']))['ugly_extra_property'] = True
116

    
117
    database_contents = execute_in_page(
118
        '''{
119
        const prom = haketilodb.get().then(db => save_item(...arguments, db));
120
        returnval(get_database_contents(prom));
121
        }''',
122
        sample_item, sample_files_sha256)
123
    assert len(database_contents['files']) == 4
124
    assert all([sample_files_sha256[file['sha256']] == file['contents']
125
                for file in database_contents['files']])
126
    assert all([len(file) == 2 for file in database_contents['files']])
127

    
128
    assert len(database_contents['file_uses']) == 4
129
    assert all([uses['uses'] == 1 for uses in database_contents['file_uses']])
130
    assert set([uses['sha256'] for uses in database_contents['file_uses']]) \
131
        == set([file['sha256'] for file in database_contents['files']])
132

    
133
    assert database_contents['mappings'] == []
134
    assert database_contents['resources'] == [sample_item]
(4-4/6)