<!DOCTYPE html>
<!--
  Copyright 2022 The Cobalt Authors. All Rights Reserved.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!--
  Note: This is a very basic test of the existing minimal Service Worker
  functionality. This can be expanded as more functionality is implemented.
-->

<html>

<head>
    <title>Cobalt Service Worker Test</title>
    <script src='black_box_js_test_utils.js'></script>
</head>

<body>
    <script>
        var expected_event_count = 0;

        function count_event(expected_value) {
            expected_event_count += 1;
            console.log('Expected events counted:', expected_event_count)
            if (expected_value) {
                assertEqual(expected_value, expected_event_count)
            }
        }

        function test_claimable_worker() {
            navigator.serviceWorker.register('service_worker_test_claimable.js', {
                scope: './',
            }).then(function (registration) {
                worker = registration.installing;
                if (worker) {
                    console.log('claimable worker registered (installing).');
                    worker.postMessage(
                        'Registration successful, current worker state is ' +
                        'installing.');
                }
                worker = registration.waiting;
                if (worker) {
                    console.log('claimable worker registered (waiting).');
                    worker.postMessage(
                        'Registration successful, current worker state is ' +
                        'waiting.');
                }
                worker = registration.active;
                if (worker) {
                    console.log('claimable worker registered (active).');
                    worker.postMessage(
                        'Registration successful, current worker state is ' +
                        'active.');
                }

                registration.unregister()
                    .then(function (success) {
                        // Even a claimed registration will successfully
                        // unregister because unregistration takes effect after
                        // the page is unloaded, so it's not blocked by being
                        // the active service worker.
                        console.log('(Expected) unregister success :',
                            success);
                        count_event(41);
                    }, function (error) {
                        console.log('(Unexpected) unregister ' +
                            `${error}`, error);
                        assertIncludes('SecurityError: ', `${error}`);
                        notReached();
                    });
                console.log('unregister started.');


             }, function (error) {
                console.log('(Unexpected) :', error);
                notReached();
            });
        }

        console.log('Starting tests');
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.ready.then(function (registration) {
                assertNotEqual(null, registration);
                console.log('(Expected) Registration ready promise',
                    registration, 'with active worker ', registration.active);
                assertNotEqual(null, registration.active);
                count_event();
            });

            navigator.serviceWorker.oncontrollerchange = function (event) {
                console.log('Got oncontrollerchange event', event.target);
                count_event(40);
            }

            navigator.serviceWorker.onmessage = function (event) {
                console.log('Got onmessage event', event.target, event.data);
            }

            navigator.serviceWorker.register('http://..:..')
                .then(function (registration) {
                    console.log('(Unexpected) :', registration);
                    notReached();
                }, function (error) {
                    console.log('(Expected) Test invalid script URL:', error);
                    assertIncludes('TypeError', `${error}`);
                    count_event(1);
                });
            navigator.serviceWorker.register('arg:service_worker_test.js')
                .then(function (registration) {
                    console.log('(Unexpected) :', registration);
                    notReached();
                }, function (error) {
                    console.log('(Expected) Test script URL that is not http ' +
                        'or https:', error);
                    assertIncludes('TypeError', `${error}`);
                    count_event(2);
                });
            navigator.serviceWorker.register('http:%2fservice_worker_test.js')
                .then(function (registration) {
                    console.log('(Unexpected) :', registration);
                    notReached();
                }, function (error) {
                    console.log('(Expected) Test script URL with escaped slash:',
                        error);
                    assertIncludes('TypeError', `${error}`);
                    count_event(3);
                });
            navigator.serviceWorker.register('service_worker_test.js', {
                scope: 'http://..:..',
            })
                .then(function (registration) {
                    console.log('(Unexpected) :', registration);
                    notReached();
                }, function (error) {
                    console.log('(Expected) Test invalid scope URL:', error);
                    assertIncludes('TypeError', `${error}`);
                    count_event(4);
                });
            navigator.serviceWorker.register('service_worker_test.js', {
                scope: 'arg:/',
            })
                .then(function (registration) {
                    console.log('(Unexpected) :', registration);
                    notReached();
                }, function (error) {
                    console.log('(Expected) Test scope URL that is not http ' +
                        'or https:', error);
                    assertIncludes('TypeError', `${error}`);
                    count_event(5);
                });
            navigator.serviceWorker.register('service_worker_test.js', {
                scope: '/%5c',
            })
                .then(function (registration) {
                    console.log('(Unexpected) :', registration);
                    notReached();
                }, function (error) {
                    console.log('(Expected) Test scope URL with escaped slash:',
                        error);
                    assertIncludes('TypeError', `${error}`);
                    count_event(6);
                });
            // Repeat a few times to test the 'equivalent job' and finish job
            // logic.
            for (let repeated = 0; repeated < 15; repeated++) {
                navigator.serviceWorker.register('http://www.example.com/', {
                    scope: '/',
                })
                    .then(function (registration) {
                        console.log('(Unexpected) :', registration);
                        notReached();
                    }, function (error) {
                        console.log('(Expected) Test Script URL is not ' +
                            `trusted: ${error}`, error);
                        assertIncludes('SecurityError: ', `${error}`);
                        count_event();
                    });
            }
            navigator.serviceWorker.register('http://127.0.0.100:2345/')
                .then(function (registration) {
                    console.log('(Unexpected) :', registration);
                    notReached();
                }, function (error) {
                    console.log('(Expected) Test script URL with different ' +
                        `origin: ${error}`, error);
                    assertIncludes('SecurityError: ', `${error}`);
                    count_event();
                });

            navigator.serviceWorker.register('service_worker_test.js', {
                scope: 'http://127.0.0.100:2345/',
            })
                .then(function (registration) {
                    console.log('(Unexpected) :', registration);
                    notReached();
                }, function (error) {
                    console.log('(Expected) Test scope URL with different ' +
                        `origin: ${error}`, error);
                    assertIncludes('SecurityError: ', `${error}`);
                    count_event();
                });

            // Finally, test a succeeding registration.
            navigator.serviceWorker.register('service_worker_test.js', {
                scope: 'registration/scope',
            })
                .then(function (registration) {
                    console.log('(Expected) Registration Succeeded:',
                        registration);
                    assertNotEqual(null, registration);
                    // The default value for RegistrationOptions.type is
                    // 'imports'.
                    assertEqual('imports', registration.updateViaCache);
                    assertTrue(registration.scope.endsWith(
                        'registration/scope'));
                    count_event(24);

                    worker = registration.installing;
                    if (worker) {
                        worker.postMessage(
                            'Registration with scope successful, current ' +
                            'worker state is installing.');
                    }
                    worker = registration.waiting;
                    if (worker) {
                        worker.postMessage(
                            'Registration with scope successful, current ' +
                            'worker state is waiting.');
                    }
                    worker = registration.active;
                    if (worker) {
                        worker.postMessage(
                            'Registration with scope successful, current ' +
                            'worker state is active.');
                    }

                    registration.onupdatefound = function (event) {
                        console.log('Got onupdatefound event',
                            event.target.scope);
                        assertTrue(event.target.scope.endsWith(
                            'registration/scope'));
                    }

                    // Check that the registration has an activated worker after
                    // some time.
                    window.setTimeout(function () {
                        // TODO(b/234659851): Investigate whether this should
                        // resolve or not, in this case where there already is
                        // an active worker.
                        navigator.serviceWorker.ready.then(function (
                            registration) {
                            assertNotEqual(null, registration);
                            console.log('(Expected) Registration ready promise',
                                registration, ' with active worker ',
                                registration.active);
                            assertNotEqual(null, registration.active);
                            registration.active.postMessage(
                                'Registration ready received after waiting.');
                            count_event();
                        });
                        // Since these events are asynchronous, the service
                        // worker can be either of these states.
                        console.log(
                            'Registration active check after timeout',
                            registration);
                        assertNotEqual(null, registration.active);
                        registration.active.postMessage(
                            'Registration is active after waiting.');
                        console.log('Registration active',
                            registration.active, 'state:',
                            registration.active.state);
                        assertEqual('activated', registration.active.state);
                        count_event(31);
                        registration.active.onstatechange = function (event) {
                            console.log('Got onstatechange event',
                                event.target.state);
                        }

                        // Repeat a few times to test the 'equivalent job' and
                        // finish job logic.
                        for (let repeated = 0; repeated < 5; repeated++) {
                            registration.update().then(function (registration) {
                                console.log('(Expected) Registration update ' +
                                    'Succeeded:', registration);
                                assertNotEqual(null, registration);
                                count_event();
                            }, function (error) {
                                console.log('(Unexpected) :', error);
                                notReached();
                            });
                        }

                        registration.unregister()
                            .then(function (success) {
                                console.log('(Expected) unregister success :',
                                    success);
                                count_event(37);
                                // Finally, test getRegistration for the unregistered scope.
                                navigator.serviceWorker.getRegistration(
                                    'registration/scope')
                                    .then(function (registration) {
                                        console.log('(Expected) getRegistration Succeeded:',
                                            registration);
                                        assertTrue(null == registration ||
                                            undefined == registration);
                                        count_event(38);
                                    }, function (error) {
                                        console.log('(Unexpected) :', error);
                                        notReached();
                                    });
                                test_claimable_worker();
                            }, function (error) {
                                console.log('(Unexpected) unregister ' +
                                    `${error}`, error);
                                assertIncludes('SecurityError: ', `${error}`);
                                notReached();
                            });
                    }, 500);

                    // Test getRegistration for a non-registered scope.
                    navigator.serviceWorker.getRegistration('/bo/gus')
                        .then(function (registration) {
                            console.log('(Expected) getRegistration Succeeded:',
                                registration);
                            assertTrue(null == registration ||
                                undefined == registration);
                            count_event();
                        }, function (error) {
                            console.log('(Unexpected) :', error);
                            notReached();
                        });

                    // Test getRegistration for a deeper registered scope.
                    navigator.serviceWorker.getRegistration(
                        'registration/scope/deeper')
                        .then(function (registration) {
                            console.log('(Expected) getRegistration Succeeded:',
                                registration);
                            assertNotEqual(null, registration);
                            assertEqual('imports', registration.updateViaCache);
                            assertTrue(registration.scope.endsWith(
                                'registration/scope'));
                            count_event();
                        }, function (error) {
                            console.log('(Unexpected) :', error);
                            notReached();
                        });

                    // Test getRegistration for a shallower registered scope.
                    navigator.serviceWorker.getRegistration('registration')
                        .then(function (registration) {
                            console.log('(Expected) getRegistration Succeeded:',
                                registration);
                            assertTrue(null == registration ||
                                undefined == registration);
                            count_event();
                        }, function (error) {
                            console.log('(Unexpected) :', error);
                            notReached();
                        });

                    // Test getRegistration for a non-registered scope.
                    navigator.serviceWorker.getRegistration()
                        .then(function (registration) {
                            console.log('(Expected) getRegistration Succeeded:',
                                registration);
                            // TODO(b/234659851): Investigate whether this
                            // should return a registration or not, in this case
                            // where there is a registration with a scope.
                            assertTrue(null == registration ||
                                undefined == registration);
                            count_event();
                        }, function (error) {
                            console.log('(Unexpected) :', error);
                            notReached();
                        });

                    // Finally, test getRegistration for a registered scope.
                    navigator.serviceWorker.getRegistration(
                        'registration/scope')
                        .then(function (registration) {
                            console.log('(Expected) getRegistration Succeeded:',
                                registration);
                            assertNotEqual(null, registration);
                            assertEqual('imports', registration.updateViaCache);
                            assertTrue(registration.scope.endsWith(
                                'registration/scope'));
                            count_event();
                        }, function (error) {
                            console.log('(Unexpected) :', error);
                            notReached();
                        });
                }, function (error) {
                    console.log('(Unexpected) :', error);
                    notReached();
                });
        }

        assertEqual(undefined, self.clients);

        console.log('Done starting tests');
        setupFinished();
        window.setTimeout(
            () => {
                console.log('Events:', expected_event_count)
                assertEqual(41, expected_event_count);
                onEndTest();
            }, 3000);

    </script>
</body>

</html>
