Subject Module Project in Computer Science

Exam group number: S2026631-3

Project title: Server Liquid Dispenser

Group Members: Andreas Work - 66712 - [email protected] Bastian Inuk Christensen - 66523 - [email protected] Frida Valles Kirkegaard - 65451 - [email protected] Simon Damtoft Bjergø - 66818 - [email protected] Supervisor: Sune Thomas Bernth Nielsen

Date: 03/06-2020 4th semester - spring

Number of characters: 58.600

Number of standard pages: 25 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

1.0 Abstract

This paper seeks to streamline the process of ordering and automate the creation of drinks. While a machine for creating drinks was proposed was not completed. The paper starts out exploring the project management methodology. Here the project made use of user stories, Kanban and a use case diagram. User stories were used to find the scope of the project. Kanban was used for time management and use case diagram was used to further develop the use for the app. Only an app for android and server is made. The server is made in the language Swift using Vapor as a framework. The server would be used by admins or owners of the machines and would contain the drinks available. The server also contains a database of the users who signed up using the app. The app was made in the IDE android studio in the language Java. The app would be used by customers to sign up and order. The app and server communicate using HTTP headers. The project concludes with a system with the quintessential parts of the streamlining, but further development and a machine to create the drinks are needed, before real life implementation is possible.

2 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

Tabel of Content

1.0 Abstract ...... 2

2.0 Introduction ...... 4

3.0 Problem formulation ...... 5

4.0 Preparation ...... 5 4.1 User stories ...... 5 4.2 Kanban ...... 8 4.3 Use case diagram ...... 10

5.0 The Server - Code Explanation ...... 11 5.1 What is a server? ...... 11 5.1.1 What is a database? ...... 12 5.1.2 REST & API ...... 12 5.2 Language and Framework Choice ...... 13 5.2.1 Swift ...... 13 5.3 Communication with the Machine ...... 14 5.4 Communication with the App ...... 17 5.4.1 Algorithm ...... 17 5.5 Limitations of the Code ...... 18 5.5.1 Known bugs of our code ...... 19 5.6 Testing ...... 19

6.0 The Autobar app - Code Explanation ...... 22 6.1 Languages ...... 22 6.1.1 Java ...... 22 6.1.2 XML Resources ...... 23 6.2 Main Activity ...... 23 6.2.1 ServerRequest ...... 27 6.3 SignUpActivity ...... 28 6.3.1 LoginType ...... 28 6.4 MainMenuActivity ...... 30 6.5 SupportEmail ...... 33 6.6 OrderDrinkActivity ...... 34 6.7 Testing ...... 36

7.0 Discussion ...... 37

8.0 Conclusion ...... 38

9.0 Perspectivation ...... 39

10.0 Bibliography ...... 40

3 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

Github Links This project has two accompanying git repositories, these can be found on the following links, marked which part of the project they belong to. The app and server can likewise be found in the zip file in the appendix. Server: https://github.com/BastianInuk/DrinkServer App: https://github.com/PlanInAdvanc/Drinkapp

2.0 Introduction

In our everyday life, it is a very common occupation to go to bars and enjoy a good time with friends. But as technology develops, people are getting more impatient at the speed of a human, wanting everything, such as Cuba Libre, faster than ever. And in recent times, an even bigger problem, hygiene, has come up. For those reasons, this project seeks to find a way to streamline bars more efficiently, so it would make more money, satisfy customers and at the same time be more sanitizable. To do this, the concept coined ‘Autobar’ was created, where the customer could order drinks with an app, henceforth referred to as ‘Autobar App’, and the drinks would be made entirely by a machine. The machine, coined ‘The Drinkinator’ would be able to automate the making of the drinks, making it more sanitizable than if a regular bartender made a drink, make physical queues a thing of the past and potentially help the problem with drug spiking of drinks. While the ‘Drinkinator’ is a great concept, we also had to consider if a bar needed multiple machines due to a larger number of customers. We also envisioned quality of life features, such as displaying which drinks are unable due to shortage of stock. Because of this, a central server would be needed to make ordering a smooth and make the AutoBar concept more scalable. The server is what differs our concept from already existing automated drinking services on the market. This project will describe how the server and AutoBar App are programmed and the obstacles we had while making it, our thoughts about design choices and a conclusion that will summarize the whole project. With this in mind, the problem formulation was made.

4 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

3.0 Problem formulation

“How can we streamline the construction of drinks by automatizing it, and the process of ordering it?”

4.0 Preparation

When starting the project, we had to get an overview for how the project should take shape, how to delegate the work, due to the scale and different elements. The first thing we did was to make user stories, to get an understanding of why and whom we wanted to make the server, app and potential machine for. Next a Kanban was made. We made use of Kanban, as to keep track of the progress of different elements and make better use of time. Last but not least, a use case diagram was made for the app. We chose to only make one for the app, as it is the only part of our code that a customer would interact with. A lot of changes have been made since the beginning of the project, especially after some unforeseen events, but the original plan is still the same, as intended.

4.1 User stories

In this section, we will describe our User Stories. User story is an agile software development tool, used to describe users' use for the product in its final form (Visual Paradigm). These informal descriptions of how the server, app and potential machine is going to function, who our target audience is, and give an overview of what was expected of our own program. First of all, we made a description of our potential customers. Here there are two different types of customers; The customers that want to buy our machine/server, and the customers that are going to use our app. For the first type of customers, there is only one target audience. A place that sells alcohol, with customers that have smartphones such as bars or nightclubs.

5 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

For the customers for the app, our target audience is everyone with the following traits. - 18+ year olds, who drink We want our app to be for people above 18 years old due to the alcohol law, that says people below the age of 18 cannot buy alcoholic beverages in bars/nightclubs. - Attends bars/nightclub Our customers need to attend places where they serve alcoholic beverages, and here the bars/nightclubs are in mind. - Smartphone Owners. The last and most important thing on the list is that the customers have a smartphone, as the concept hinges on the use of an app. Due to time constraints, prior knowledge of Java coding and availability, we choose to only make the app for Android. Below is the table for the user stories. Here it will be explained in short sentences what the app should be able to do, as if a customer would be explaining the app.

Epic No. User story (As a user, I can…) Elaborated user story

Registration 1.1 Fast registration, as little Full name, age, username, e-mail, information as possible phone number

1.2 Confirmation email or SMS To validate user

1.3 Available from Android app Written in Java

Login 2.1 Login page Register or login

2.2 Change password If forgotten

Account 3.1 See personal information Possible to change it

3.2 See order history See ordered beverage history

6 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

3.3 See queue with the usernames An estimated time, for when the drink is done

3.4 Send an email to support If trouble occurs, the user can send an email to a support email.

Order 4.1 See menu Different beverages and mix your own.

4.2 Add to basket See basket - only one drink is possible to order at the same time.

4.3 Fast and secure payment Through Nets or MobilePay (or third)

4.4 SMS when drink(s) is done Preferably a minute or two before, so the user can get it in time.

Serving 5.1 The drink can only be taken by the Some kind of code or QR person who has ordered it.

This was this initial idea of the scope of the app. Some of the ideas have not been fulfilled in the finished product, due to time constraints. This will be further explored in the discussion and perspectivation.

7 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

4.2 Kanban

Illustration 1: Our Kanban board can be seen. Here it has six different stages as columns, that represent how far a part of the program is being done. Those closer to the right, means they are closer to being done (Lucid Software Inc., 2020). The Kanban board was last updated on the 24th, this is on purpose, we wanted to show a Kanban board that wasn’t completely done, to show the different parts of a Kanban board, which is an agile workflow management method designed to visualize what needs to be done (Kanbanize). As seen in illustration 1, it has six different columns, where they have different functions. Backlog is where everything starts, it's an idea that needs to be executed. This is also the reason for it to still have some sticky notes because it's a thing that we want to implement as extra, but they’re not necessary to implement for the program to work. The in-progress is things that, as the name of the column, are in progress. So that's the idea, normally the different elements to the project would be separated, it was decided not to, for practical reasons. We wanted to present the process of the programming and not the report, and the report has a lot of small elements, which would only take up a lot of space on the board.

8 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

With the testing and done columns, it can be a bit difficult to separate these things. Some of the things that are in the done column are also kind of in the test column; as seen in the “stress test the whole program”, this is for two reasons. Reason one is very simple, so we don’t forget to either make the small element or to actually forget to stress test the whole program, whereas reason two, is to see how many of the small parts are actually done, and get a better overview of how much needs to be done. The last column is for the scrapped things, some of the original ideas, haven’t made it to the end. It would also just be possible to just delete these things, but we think that it’s a good idea to save them, and show what is decided not to have, here the history function are one of them, we still want it on the Kanban, so if the project is further developed, we can see some of the ideas that we were thinking of while making the program.

9 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

4.3 Use case diagram

We have decided to only make one use case diagram. A use case diagram is “a methodology used in system analysis to identify, clarify and organize system requirements.” (Rouse, Brush). It was decided to only make one use case diagram, this is to give a clear overview of how we are seeing the process of the app. Below in illustration 2, the use case diagram is shown for the drink machine.

Illustration 2: Our use case diagram can be seen. Here the actors needed for our system are shown and the association between in actors, within a system boundary (Lucid Software Inc., 2020).

In the use case diagram, the first one to be seen is the customer, here it is possible to see the steps the customer has to go through to get their drink. The first step for buying a drink is to make sure the user is using the same WiFi as the server, this is due to the use of HTTP for the communication between the server and the app. If the idea is further developed, it would be advantageous to move away from the okhttp approach, to make it easier to buy drinks.

10 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

Next is making sure the user is logged in or sign up if the user is new to the platform. And lastly, the customer has to choose their desired drink. Both the Drinkinator and human bartender are both bartenders, with agency that creates drinks. While a machine normally does not have agency it of itself, we felt our Drinkinator machine is treated as if it has, being at the same level as a regular bartender, except for it not being able to clean and restock. For this reason, it was decided to show it as a human in our use case diagram.

5.0 The Server - Code Explanation

Our project is separated into two different parts, the first one is the server, and the second part is the app. In the following section, we will explain what a server is and how the server for this project is made. This includes the languages used, how we communicate between the server and app and an explanation of the code itself. Lastly, the limitations and tests will be explained.

5.1 What is a server?

A server is simply: “a type of computer or device on a network that manages network resources” (Beal, 2020). A server's purpose is to “manage, store, send and process data 24-hours a day” (ibid.), which is also the reason for its reliability. There are a lot of different kinds of servers and in this project a web server is used. A web server is a type of computer that delivers to a webpage, thus the name web server. A web server also has an IP address. In our project, the web server will deliver the needed data, as a JSON encoded data package, to the Autobar app. The server will also contain the login information in a database, to make it possible for users to register, and later login as needed. JSON is the format primarily used to communicate between browser and server. With JSON any JavaScript object can be turned into a JSON object (CM Consult).

11 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

5.1.1 What is a database?

A database is a collection of data, made to be easily accessible. (Rouse. Ferguson et al. 2019). The server uses SQLite (SQLite). This is due to our understanding of this specific database from our courses, so it was already on our computers. The way the server interfaces with SQLite is with the Fluent (docs.vapor.codes (a)), a library which is part of Vapor explained further below. Fluent takes advantage of Swift's typesystem to construct the tables, making it simple to make tables in our database of choice, as well as put and retrieve data. There is a total of 7 database tables in our database. These are for managing the users, drinks and machines as well as the ingredients for the latter two.

5.1.2 REST & API

An API is “[...] a set of definitions and protocols for building and integrating application software. API stands for application programming interface.” (Red Hat (a)). API is a generic term for the interface a programmer code against. This can be in relations to a library or a webservice (ibid.). If you are coding against an API, you and your app could be considered by some to be an API Consumer (Bouza, 2018). While the person, company or server which provides API’s often also can be called API provider (ibid.). “REST is a set of architectural principles, not a protocol or a standard. API developers can implement REST in a variety of ways.” (Red Hat (b)). RedHat states that information sent with REST is done so over HTTP, generally formatted in JSON (ibid.). REST is an abstract term that defines in a generic way how a client and a server communicate with each other.

12 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

5.2 Language and Framework Choice

5.2.1 Swift

For our server, the programming language Swift is used and is written in Xcode (Apple Distribution International). Swift was developed by Apple in 2015 and is a compiled, general- purpose programming language that seeks to replace C-based languages. The philosophy behind Swift is to be easy, fast and secure, and have the ability to find the errors before the program is compiled. Swift also has a very atypical syntax, so for example, they don’t have the semicolons, which again is an optimization, and also enforce writing more clean code (Swift (a)).

5.2.1.1 Vapor - framework

To support our server, there will be a framework. The supporting framework that will be used is Vapor. Vapor is a made from a small team for Swift and is used to support the foundation of a webpage or API. It will be used for API (Nelson. Wright, 2017). Vapor is “a modular framework built for a modular language.” (ibid.), which also contains packages, that are formed from modules (ibid.). Vapor has a package which allows the usage of objects to represent database tables (docs.vapor.codes (a)), this makes it fast and easy to add and iterate on the database during the development phase. Another big advantage that Vapor the framework has over PHP the language, is how routes are made. To make a route in Vapor, one registers a function, which handles these routes, and in PHP routes are registered by making a file which handles the given route. This makes it easy to write modular and reusable code.

5.2.1.2 Middleware

In Vapor it is possible to have functions making operations on the signal between the route and the client. These are called middlewares. Middlewares can be bidirectional, meaning that they can perform their operations on both incoming and outgoing signals (docs.vapor.codes (a)).

13 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

Our server has exactly two middlewares, both for ingoing signals. The first validates username and password against a database. This is so we can reuse that particular middleware on any given route if need be. The other middleware checks for a token in the HTTP header, this token is associated with a given user, and if this token isn’t present, or worse, is wrong, then the middleware returns an authorized error back to the API consumer, otherwise the middleware passes the request further to the route.

5.2.1.3 Password Security

The server does a one-way hash of the user's password, the specific algorithm used is BCrypt. Vapor provides an easy to use BCrypt API (docs.vapor.codes (b)). “Because Bcrypt uses a salt, password hashes cannot be compared directly. Both the plaintext password and the existing digest must be verified together.“(ibid.). This means that even if a hacker gets all the passwords from our database, they still have to use some processing power to get our passwords, and the passwords are not susceptible to hacking such as rainbow attacks (ibid.).

5.3 Communication with the Machine

We opted to use WebSockets for communication between the server and the drink machine. WebSockets allow for easy bidirectional communication between the server and client (WhatWG, 2020), this means it isn’t necessary to have to write a server, do polling or similar on the machine, and only worry about receiving WebSockets traffic. One of the notable parts of the code is the WebSocket code. Here we store every connection in a dictionary, with the machines UUID as key and the connection as value. This design is to not send every order to every machine, but rather keep it tight and only sends the order to the appropriate machine. To register a machine on the server, and at the same time connect the WebSocket, the machine has to start a WebSocket connection on /machine/{name}, where {name} replaces the machine name. This registers the machine on our database and generates a new machine on our server. This can be seen in MachineController.swift in the method register, as well as the global dictionary “machine”.

14 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

Illustration 3: A snippet of the code used to decode the JSON data package, when received. Here we only execute, if the package is able to be decoded (@carbon_app). The body of a given text is parsed by extending String to have the method evalBody, which takes two arguments, any decodable type and a callback which takes the argument passed in as type. We try to decode the String as the type in question and if it succeeds, the decoded instance is passed into the callback. This is done using one of Swift’s error handling, where a throwing function returns nil if it’s not successful (Swift (b)).

15 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

Illustration 4: A snippet of usage of the method evalBody, which handles inbound JSON data packages from the machine (@carbon_app). If we take a look at line 7 through 9 in illustration 4, the use of evalBody can be seen. This specific usage of the method was for a proof concept if the machine sends a valid UserContent, then the mail given in the UserContent will get printed. On line 12 through 28 the text is evaluated as a RanOut type, and if it’s that, the ingredient entry is deleted and replied to the machine that the entry has been deleted.

16 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

5.4 Communication with the App

There are two controllers on our server which handles communication with the app. In the UserController.swift file the user credentials creation and validation are handled, as well as handling the logout. The DrinksController.swift file handles all communication with the app in relation to the drink. This is where the server receives the orders, handles new recipes and ingredients and also sends the menu out to the users. All this communication is done through REST.

5.4.1 Algorithm

When a user of the AutoBar app opens the menu, the menu only displays the available drinks. This does this by querying all of the ingredients on the machine. When finished, the server then proceeds to query all the drinks associated with the ingredients. Before sending the drinks to the API consumer, the server filters the drinks, so drinks with unavailable ingredients or duplicate drinks will not get sent to the user.

17 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

Illustration 5: A snippet of the code used to query all available drinks and return an array with the available drinks, and remove duplicates (@carbon_app).

5.5 Limitations of the Code

In our program, there are a couple of limitations, which comes to a down problem; time. It would be possible to solve a lot of the limitations/problems that we have if there was more time. One of the main limitations our program has, is that the API can only order one drink per HTTP request, which means that a customer has to go through the order again, or the app has to send multiple requests per order if they want multiple drinks. This is a big limitation and problem for our program, because we want it to be possible for the customer to order for friends and/or order multiple drinks at the same time for themselves.

18 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

5.5.1 Known bugs of our code

The server also contains some bugs. The first and most pressing bug is the method which queries all available drinks to the user, this method queries by ingredients the machine has. Unfortunately, as long as the machine has an ingredient, all recipes for this ingredient will get queried, and recipes with some unavailable ingredients won’t get filtered. Another bug is the token middleware. The idea behind this middleware is to only allow traffic through if there is a valid Authorization Token present in the HTTP request. This middleware is unfortunately not working, and we could not figure out what the issue was. These bugs are like the rest of the limitations, something which could be solved given a larger time horizon.

5.6 Testing

For testing the server, white and black box testing as manual tests was used. Afterwards, some automatic integration tests using grey box testing were made. Lastly, we did a stress test for the server to see how it handled multiple requests. For the manual tests for the server raw HTTP requests and WebSocket messages were sent. The tools used for those tests are a REST Client called Paw (Paw cloud, 2020) and a WebSocket Client aptly named WebSocket Client (AwayUp, 2018). White box testing is when the person that tests has knowledge of the structure of the code/program and how to program, so the developer is going to conduct the white box testing. The white box testing is a test form that will test the internal functioning of the program (Guru99 (a), 2020). Under the white box testing breakpoints with a debugger was used extensively while testing. Normally debugging isn’t a test form, but just debugging an error in the program. (pp_pankaj, ashushrma378). The black box testing is somewhat the opposite of white box testing, this is because the tester doesn't have knowledge of the structure of the program. This test form will test the external expectations; it will test the program, to see if it reacts as it should react. In our project, it would be to see if the server reacts correctly when a drink is ordered (ibid.).

19 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

For executing the black box testing for the server GitHub was used (GitHub Inc., 2020). Githubs feature, ‘GitHub Actions’, automatically tests a code when uploaded. GitHub Actions are automatically run on any given event, these can be push/pull requests or make a custom webhook (GitHub Help). Grey box testing and integration tests were used at the same time. In grey box testing, the code is partially known and will test for errors due to incorrect or bad code structure or incorrect functioning of the program (Guru99 (b), 2020). This combined testing was used, because we wanted to test the program as a whole, and therefore, have some knowledge of the program and how it should react. This is also the reasoning of integration testing; it will test the units combined, to make sure the program works together without any errors (Roy, 2020). It is important to have tests that will be executed during and after the program is done, here to test if the program works as originally intended. Lastly, we wanted to make a stress test for our server. A stress test means that we will test the program, to see how long and how durable the program is. The main reason a stress test was made for our program was to make sure that our program wouldn’t crash when under heavy load. Our program is intentionally going to be able to have multiple users at the same time because it's going to potentially have a full bar worth of users per machine. It is only possible to make an efficient stress test when the whole server and app is done (Guru99 (c)). When the stress test was made, a shell script was written, which did 10.000 requests which lasted five minutes and one second. The script itself asks for every available drink at a given machine, orders a Cola and prints which request number it is. This is two HTTP requests per request. The stress testing script, seen in illustration 6, is written in ZSH, a command-line interpreter or shell and the default shell for macOS (Heddings, 2019).

20 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

Illustration 6: Our stress test script. Here we continually order the same order 10000 times, to see if the server crashes. Then printed the start and end time of the script (@carbon_app). The machine used for testing the program is a MacBook Pro with 2,4GHz Quad-Core and 8GB of memory. During the stress test, the server of the developing machine reached a max of 40% CPU usage and with a minimum of 30% CPU and the RAM usage was approximately around 9,9MB of RAM. The conclusion of the different ways of testing our server was that the results are as expected. Both white, black and integration tests all worked and could be executed without showing any errors. The result of the stress test, also showed that our server is very stable, and can handle a lot more than was tested, which is as expected, and could potentially be expanded to have even more customers to multiple machines.

21 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

6.0 The Autobar app - Code Explanation

The app would be the place where our customers can sign up, log in, pick a drink to buy, find out more about the concept and more. The following section will be describing the languages used, design choices, the notable elements of the code and testing for the app. When creating the communication between the app and the server, we made use of two external libraries. This being Gson (Google, 2020) and OK HTTP (Square. Inc.) libraries.

6.1 Languages

6.1.1 Java

The app itself is written in the IDE “Android Studio”. Android Studio, as the name implies, is an IDE designed for android app coding (Google. JetBrains, 2020). The app is written in Java programming language. Java was created in the early 1990s by Sun Microsystems. It is an object-oriented programming language, and the syntax is very similar to the C-based languages (Free Java Guide). When created, they had five goals, of how Java should work; “1. It should use the object-oriented programming methodology. 2. It should allow the same program to be executed on multiple operating systems. 3. It should contain built-in support for using computer networks. 4. It should be designed to execute code from remote sources securely. 5. It should be easy to use by selecting what was considered the good parts of other object-oriented languages.” (freejavaguide). These five goals are also the reason for Java’s popularity, and the reason that it is widely used. It is fast to program, easily learned due to its similarity to C and C++. Java, however, is more secure and robust, because it doesn’t contain references to data externals, doesn’t use pointers and also runs in an isolated testing environment (Rouse, McKenzie, 2019).

22 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

6.1.2 XML Resources

In app development resources are the name for files and static content such as layout definitions, UI (user interface) strings etc. This is done in XML, a markup language which helps the developer more easily get an overview of the design. (Android Developers (a), 2020) In our project, four different kinds of resources were used. Layout, drawable, menu and values were used. Layout files define the UI for the app. The layout of the UI contains different components called widgets (Android Developers (a), 2019). Widget used in our project includes buttons, textField, EditText etc. Widgets all make use of attributes, such as the attribute android:id, for creating unique resource names, placement in the app, size etc. With these widgets, it is possible to manipulate the logic and functions, using our java code (ibid.). Drawable files are bitmap files or XML files that show a static graphic. For our project, we mostly made use of the default pictures within Android Studio (o7planning.). The Menu files, which was only made use of once, are XML files related to menus, that can be hidden or shown using a prepared class called MenuInflater (Android Developers (a), 2020). The last resources file that was made use of, was the values files. These XML files contain simple values, such as strings, colours and styles of the entire app.

6.2 Main Activity

In our main activity, the first activity the user will see, we set the contentView to the appropriate XML. This is also how the layout for the rest of the activities was done. In our java code, we define our buttons and EditTexts, and use the findViewById, to set the relevant action for the component, as seen in illustration 7 and 8.

23 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

Illustration 7: A snippet of the MainActivity java code can be seen. First, the buttons and EditTexts are defined. Then our layout is set to equal the XML file called Acitivty_main. Afterwards, our buttons and EditTexts are bound to the buttons and EditTexts on the XML and lastly, the buttons are made interactable (@carbon_app).

Illustration 8: A snippet of the XML for MainActivity is seen. It is seen how we create a button and define the id of an item, which is later used in the java code. The rest of the code defines the placement and size, style and text of the button (@carbon_app).

24 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

View.OnClickListener is also implemented, which executes our OnClick(View view), when the buttons that were made are clicked, by adding the setOnClickListener to the buttons. In this case, we have the button for signing up and logging in. In our OnClick(View view), it is notable that we decided to use a switch statement as seen in illustration 9. A switch statement executes a block of code, depending on what condition is met for the expression (w3schools (a)). In this case, our expression is a button being clicked, and the condition is which of the button is being clicked. It was decided to use switch statements, as we felt they were easier to understand and more scalable. While the performance is not affected while only two buttons are used, it could be a problem if there was more.

Illustration 9: Our use of switch statements can be seen. Here our expression is which view is being clicked. We break after each code block is executed, as we only one to run one of the options (@carbon_app). The sign-up button’s only function is to start a new activity, which is our SignUpActivity, using the Intent object. Intents are messaging objects that request an action from another app component (Android Developers (b), 2019). In this case, we want to start a new activity internally within the app.

25 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

Starting a new activity stacks the new activity on top of the previous. This means that the user can use the back button on their phone to return to the previous activity. An example of this can be seen in illustration 10. This means if only Intent was used, without ending the activity, the user could potentially create a massive back stack, which could make it difficult for the user to navigate our app (Cooper, 2011). For this reason, when starting a new activity, it was always considered whether it was needed to end the current activity. The button for starting sign-up activity does not end the main activity, which will be explained further in the SignUpActivity.

Illustration 10: The activity and back stack can be seen. In this case, if the activity 2 had a button taking the user to activity 1 without ending the activity 2, the back stack would be Activity 1, Activity 2 and Activity 1 again. Continually pressing back and forth, would then create a massive back stack, forcing the user to close the app entirely (Cooper, 2011). The submit button, however, used for logging in, sends username and password to our server, which will then validate and if correct send back a token to the app. It does this, by reading the credentials from the TextEdit fields, encodes these as an enum (a representation of groups of constraints (w3schools (b))) case, which is then passed further to our ServerRequest class. If the validation is completed, and the user is found, when the MainMenuActivty was started and the current activity was ended. This is not needed in our final product, but using the back buttons led to a bug in a prior version of the app.

26 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

6.2.1 ServerRequest

ServerRequest functions as a wrapper around OK HTTP — our library of choice for sending data packages — requires that the HTTP request is run as a background process, as to not block the UI thread, which would make the app unresponsive. The way we did this was to make a general-purpose constructor, which got larger as our needs for request functionalities expanded.

Illustration 11: The DoInBackground method. Here we make use of the Okhttp library to send the requests from the app to the server (@carbon_app). This also meant that we had to employ runOnUiThread() whenever it was needed to do operations on the UI such as our use of Toast, a simple feedback popup, used to give the user responsive feedback when using the app (Android Developers (c), 2019). UI operations cannot be run in a background thread to protect against race conditions, some of which could potentially make the app cause a bug in the layout, or worse yet, give the user a bad experience.

27 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

6.3 SignUpActivity

In our SignUpActivity, there are two buttons. The button for going back is not really needed, as all it does is finish the current activity, taking the user back to the MainActivity. In this case, the button functions exactly as if the user pressed the back button on their phone, and the button is merely there to make it more intuitive for the user. By making sure this activity is ended, we make it impossible for the user to stack activities. The second button likewise makes sure to end the activity, after sending the user back to the MainActivity.

Illustration 12: Our use of switch statements and our server request can be seen. While the case for the bt go_back has the same function as if the user used the back button on their phone, itis still kept, as we felt this made our app more natural to use. We also finish the activity after the user signs up, as to prevent a backstacking issue (@carbon_app).

6.3.1 LoginType

To send a request for login or anything else, it was needed to send a JSON data package to the server. To differentiate between a login and a regular token, it was decided to use an enum. The enum simply changes what kind of authorization/authentication information is sent. This way, the app would not need multiple classes and it would make our code cleaner. We were,

28 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712 however, unable to make the token authentication function correctly server side. This was kept, as it would make it easier to further develop the app. This information is sent as part of the HTTP Header in the Authorization header.

Illustration 13: The different options for the enum can be seen. Currently, only LoginType basic is used, which sends a Base64 encoded message with the username and password to be verified by the server. The token would be used for the server, so the app does not have to store username and password (@carbon_app).

29 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

6.4 MainMenuActivity

In our MainMenuActivity, we make use of fragments. A fragment is a layout that only shows in part of an activity UI and is nested in the activity (Android Developers (d), 2019). A custom toolbar was created to show a navigation menu, where the user is able to go to other menu panels. This is done by creating two XML files, Illustration 14 and 15 respectively, where our toolbar and our navigation menu was created. Inside the toolbar, the navigation icon was used as a button, as we felt this was the most responsive way to create a button. To make the toolbar look as natural as possible, we wanted it to occupy the space the action bar normally takes. For this reason, the default theme in the styles XML file was changed, and chose one that would remove the action bar.

Illustration 14: The toolbar XML can be seen. We choose the icon for our navigation button, and at the same time make it interactable, as if it was a button. (@carbon_app) Then a menu layout file was created, containing the different tabs we wanted. This was done by creating a group of items with the checkableBehavior to single. This means, the user will only be able to check off one of the options, which is the most logical, as the buttons are used for changing the shown fragment.

30 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

Illustration 15: Our XML file for the menu is seen. Here we created a group of items, and gave all items IDs, icons functioning as buttons and a title, to explain which fragment the navigation icon opens (@carbon_app). By using fragments, the layout of the activity was changed. However, we wanted to keep the toolbar with the navigation menu, when the user changed tabs. This is done by setting our toolbar and our navigation in the XML file for the MainMenuActivity, and after setting those, we have a FrameLayout, which will load the XML layout file according to which Activity fragment is being used.

31 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

Illustration 16: The XML file for the MainMenuActivity can be seen. The entire frame is a drawer layout. In here, we add our main_menu and toolbar XML files (Illustration 14 and 15) before adding a FrameLayout. This way, the fragment will change the FrameLayout, but keep the navigation and toolbar intact. The navigation menu also included a custom header to make it look neater (@carbon_app). With this XML file, our java code was created. Here we first call our custom toolbar, by using the setSupportActionBar. This is how the toolbar is made to occupy the space the action bar would. The navigation view is then called and makes the navigation menu fill the entire activity, by having it replace our drawer layout. We also make sure to bring to the front, to evade other features overlapping, and making further development easier. Then the getSupportFragmentManager method is used to change between the fragment activities, which each has a corresponding layout XML file, replacing only the FrameLayout, to

32 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712 keep the navigation and toolbar. To replace the fragments when a user went to a different activity, switch statements were once again made. While it is possible to close down the navigation view by clicking somewhere that is not part of the menu, due to our use of an ActionBarDrawerToggle type, we felt it was more natural to press the back button on the phone. For this reason, the OnBackPressed function was used. In this function, if the menu is out, the menu is closed, instead of closing the activity, as would normally happen. If our menu isn’t open, the back button functions as normal, as seen in illustration 17.

Illustration 17: Our OnBackPressed function is seen. Here we have the condition that if the menu is open, the menu is closed when the back button is pressed. Else, if the menu is not open, we use the back button as normal (@carbon_app).

6.5 SupportEmail

The intent that was used for the rest of the app, have all been internal. However, in the SupportEmail activity, we wanted to make it as easy as possible for the user to email for help. To do this, a button was made with a different kind of intent, the Intent.ACTION_SEND. This intent sends the information through another app, in this case, the users default email app, with our email, an appropriate title and the text the user wrote inside the app itself. For providing the email, title and text, we made use of the putExtra to add extended data to the intent.

33 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

Illustration 18: The java code for when the user presses the button can be seen. Here we use the intent.Action_send and putExtra to fill out the email when the user opens their email, to make it easier emailing us (@carbon_app).

6.6 OrderDrinkActivity

In the OrderDrinkActivty, a recyclerview was used, the officially endorsed view for lists in an app (Android Developers (b), 2020). What makes recyclerview great for long datasets, is the fact that they only hold onto the view of an item, if it is displayed on the screen or is just out of bound. When the item view exits the screen, it’ll be re-bonded to a new item (ibid.). Each position, text, image etc, is managed by an adapter using the OnBindViewHolder() type as seen in illustration 19.

Illustration 19: Our OnBindViewHolder is seen. Here the name, image and whether it has been clicked by the user is updated (@carbon_app).

34 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

When the activity view is opened, a request is sent to the server, to retrieve every available drink on a given machine. To make this response into drinks, the function like on illustration 20 is needed. A for loop is added for each drink retrieved, alternatively the functional map method could achieve the same, but to show that there were different ways of handling this, we opted to use the for loop that is used now. To build the list we ran the showDrinkRecycleView, which updates the adapter with the number of drinks and names on the UI thread as the very last step. Everything prior runs on a background thread to not make the system unresponsive in the case of a large number of available drinks.

Illustration 20: A snippet of the code of OrderDrinksActivity can be seen. In the switch statement, we update the Arraylist if given a HTTP response code. The HTTP response code (200), means it was succeeded in getting a response from the server. The ArrayList was then updated, using a loop. Lastly, we show the recycler view in the foreground (@Carbon_app). Due to the nature of the recyclerview, we could not make use of the normal onClickListener that was used before. Instead, the OnItemClick had to be inside the adapter and save the position in the ArrayList for the operations. The position was then updated for each time an item was clicked.

35 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

Illustration 21: A snippet of the code in the adapter is seen. Here we make use of the OnItemClick and save to position. We do this for each time an item is clicked and update the position (@carbon_app).

6.7 Testing

For testing the Autobar app, manual testing is exclusively used in the form of white- and blackbox testing. Debugging will also be used as a test form. For the blackbox testing, the android emulator included is used in the android developer kit. Here we extensively tried to check if all aspects of the app were functioning correctly, and actively tried to break the app in the emulator, all this without thinking about how the code works. For the white box testing, print statements were made to see if the app executed all code where it was difficult to know by blackbox testing. The debugger was also used as a test form, to see if the callbacks for the JSON data packages were encoded correctly, before our integration with the server.

36 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

7.0 Discussion

In this discussion, we will be discussing the choice of not creating the source code or the physical machine of the Drinkinator and the scalability of the concept. We will also explore some of the scrapped parts of the app and consider the importance of those missing features. In our project, the first idea was to build a physical machine with an inbuilt server using a microcontroller, such as Raspberry Pi. This machine would work properly, pour drinks and deliver the drink by conveyor belts out of the machine. Having the physical working machine would make it easier to test the product, and it could be argued. We cannot know if our streamlining actually has an impact, if the machine is not implemented in a bar. This was partly done, as the Drinkinator machine would shift the focus away from the server and app, which would comprise most of the code. Another reason for not making the machine, which was not a decision made by the group, was due to the RUC lockdown. Because of the lockdown, it was not possible to have access to neither materials nor the equipment to build a machine. As an alternative, we considered making an emulator that could simulate and show how the Drinkinator would function. We also decided against using an emulator, as even without it, we would still be able to do tests of the app and server. Not having the Drinkinator or emulator does ruin a few of our original ideas, such as having increased protection against spiking of drinks. But the end product does contain the essence of what the group wanted to do, and we left plenty of room for further development due to the architecture of our code. Giving room for further development was a big part of the structure of the code. As mentioned before, a lot of tools were used to make the app and server as scalable as possible e.g using switch statements for navigation or using a scrollable recyclerview to display drinks. Another big consideration was the placement of the server. While we originally wanted to keep it on the microcontroller, it was later realized that the server would be a lot easier to upscale if it was in our possession. This way, we wouldn’t have to change every Drinkinator if a new price is wanted. Furthermore, customers would have a difficult time using different machines, unless a centralised system was made to keep track of logins. This, however, would essentially do the same as our server.

37 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

While we got the quintessential parts of the AutoBar app functioning, there are still a lot of unfinished parts due to time constraints. Some of these missing features are merely quality of life features, such as having a more personalised account. While it would be neat to have those features, it does not feel like a huge loss. But some of the features feel detrimental not having. For instance, as the product is now, it is only possible to order one drink at the time. Paying for a round of drinks is a common occurrence, and therefore something that should have been prioritized higher on our Kanban board. Another great feature, that was close to being implemented, was a custom drink menu. Here the plan was having multiple recyclerviews, where the user could either order a pre-made drink or customize a drink by all available alcohol and fizzy drinks.

8.0 Conclusion

This project's start was to streamline the construction of drinks and the process of ordering them. Our idea to streamline the construction was to build a machine that was controlled by an app, which is connected to a server. To know the scope of the project, the system architecture and keep track of time, we made use of the agile workflow management methods Kanban, User stories and use case diagram. Not all of these ideas and goals were reached due to the sudden lockdown of Denmark. But it did give an indication of what the final product would look like. The biggest aspect of the original planning, that was not fulfilled, was the idea of a physical machine. It is debatable whether our project is viable in real life, as we were unable to test it, and do not have the machine made. The machine ended up not being built due to the lockdown. While this was originally a letdown, we discovered that it was actually more easily scalable using an external server instead of using a Raspberry PI microcontroller, as originally proposed. Without the machine, however, a lot of our original expectations were ruined, as the project was more focused on the server and app. The server was written in Swift, made use of the Vapor framework and used SQLite as a database to store users. The server communicates with the app by WebSockets. One of the biggest limitations of the server was the fact that it can only handle one drink request at the time. This limitation is huge, and something we should have thought about earlier, and

38 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712 incorporated into our planning or Kanban. Another aspect was the token authentication. This would also have made a great addition to the server and app communication. The testing, however, was great. Our server is easily able to handle even the most business nights, being able to take 10.000 requests within 5 minutes, without crashing. The Autobar app also had a lot of limitations. This was due to both server-side issues and unexpected difficulties programming the order pages and communication between the app and server. But we still ensured our project was scalable, if we wanted to further develop.

9.0 Perspectivation

In this perspectivation we want to give a last comment on this project, and our thoughts about the whole idea and the ability to further develop the app and here also a potential machine. We are happy with the results, for the given project and the given time, we reached our goal despite some different obstacles, some of them history book worthy. Our original goal was to build a machine that would work with the server and app. After some time and thinking, we are happy that we scrapped that idea. If this machine was going to be built in real life, we want it to fit the specific bar and their needs. Some bars want a machine, that have only different beers, some only different shots and some others a little bit of everything. Our business model would be that all the machines are unique, but share the same app and server, which is also making this project unique from all the others already existing drink machines. Another thing is that it has to be secure, the drink has to be “locked” in, and only the person that orders, needs to have access to the drink, this is to avoid drink spiking and to have basic hygiene. With the app and server, we have already discussed some of the limitations our server and app has further up. The biggest limitation is the one drink feature, if further developed, this would be one of the first things, to actually change. Some of the other things that would be included are also listed in the Kanban in the chapter of ‘Work process’, these are the quality of life, these contain; happy hour, easy button to same drink feature, and custom-made drink. The good of our server and app is that it does not have a limitation of the features it can hold and can be changed easily with updates from the users perspective. Which is also why we decided to have one server and one app, that can contain a lot of different machines. We want it to be unique, but still with easy access.

39 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

10.0 Bibliography

• @Carbon_app: [Online software] [Last accessed 1st June 2020, 13:11 o’clock]

• Android Developers (a) (2019): App Widgets Overview. [Online] [Last accessed 1st June 2020, 16:25 o’clock]

• Android Developers (a) (2020): App resources overview. [Online] [Last accessed 1st June 2020, 16:25 o’clock]

• Android Developers (b) (2019): Intents and Intent Filters. [Online] [Last located 1st June 2020, 17:08 o’clock] • Android Developers (b) (2020): Create a List with RecyclerView. [Online] [Last accessed 1st June 2020, 16:26 o’clock]

• Android Developers (c) (2019): Toast overview. [Online] [Last located 1st June 2020, 17:09 o’clock]

• Android Developers (d) (2019): Fragments. [Online] [Last located 1st June 2020, 17:09 o’clock]

• Apple Distribution International: [Computer app] [Downloaded 8th February 2020, 10:32 o’clock]

• AwayUp (2018): [Computer app] [Downloaded 20th February 2020, 11:42]

• Beal, Vangie (2020): server. [Online] [Last accessed 9th May 2020, 13:17 o’clock]

40 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

• Bouza, Amancio (2018): 4 Stakeholders of API. [Online] [Last accessed 1st June 2020, 16:32 o’clock]

• CM Consult: JavaScript Object Notation (JSON). [Online] [Last accessed 1st June, 18:39 o’clock]

• Cooper, Bruce (2011): Activities, Tasks and Intents, Oh My! [Online] [Last located 1st June 2020, 16:43 o’clock]

• docs.vapor.codes (a): Fluent → Overview. [Online] [Last accessed 20th May 2020, 14:32 o’clock]

• docs.vapor.codes (b): Security → Crypto. [Online] [Last accessed 20th May 2020, 14:32 o’clock]

• Free Java Guide: History of Java programming language. [Online] [Last accessed 9th May 2020, 15:32 o’clock]

• GitHub Help: Events that trigger workflows. [Online] [Last accessed 21st May 2020, 15:35 o’clock]

• GitHub Inc.(2020): [Online] [Last accessed 1 st June 2020, 17:57 o’clock]

• Google (2020: [Library] [Last used 2nd June 2020, 17:25 o’clock]

• Google. JetBrains (2020): [Computer program] [Downloaded 28th February, 10:42 o’clock] • Guru99 (a) (2020): Black Box Vs. White Box Testing: Key Differences. [Online] [Last accessed 29th May 2020, 12:23 o’clock]

41 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

• Guru99 (b) (2020): What is Grey Box Testing? Techniques, Example. [Online] [Last accessed 29th May 2020, 12:23 o’clock]

• Guru99 (c) (2020): What is STRESS Testing in Software Testing? Tools, Types, Examples. [Online] [Last accessed 2th May 2020 y, 13:32 o’clock]

• Heddings, Anthony (2019): What is ZSH, and Why You Should Use it Instead of Bash? [Online] [Last accessed 28th May 2020, 15:30 o’clock]

• Kanbanize: Kanban Explained for Beginners. [Online] [Last accessed 2nd June 2020, 16:40 o’clock]

• Lucid Software Inc. (2020): [Online software] [Last accessed 1st June 2020, 12:30 o’clock]

• Nelson, Tanner. Wright, Logan (2017): Vapor Documentation. [Online] [Last accessed 14th May 2020, 16:35 o’clock]

• O7planning: using image assets and icon assets of Android Studio. [Online] [Last located 1st June 2020, 16:55 o’clock]

• Paw Cloud (2020): [Rest Client] [Downloaded 20th February 2020, 11:50]

• pp_pankaj, ashushrma378: Difference between Testing and Debugging. [Online] [Last accessed 2nd May 2020, 14:32 o’clock]

• Red Hat (a): What is an API? [Online] [Last accessed 1st June 2020, 17:43 o’clock]

• Red Hat (b): What is a REST API? [Online] [Last accessed 1st June 2020, 17:45 o’clock]

42 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

• Rouse, Margaret. Brush, Kate: What is a Use Case? [Online] [Last accessed 1st June 2020, 14:21 o’clock]

• Rouse, Margaret. Ferguson, Kevin et. al (2019): What is a Database. [Online] [Last accessed 2nd June 2020, 12:10 o’clock]

• Rouse, Margaret. Mckenzie, Cameron (2019): Java. [Online] [Last accessed 11th May 2020, 15:04 o’clock]

• Roy, Shilpa Chatterjee (2020): What is Integration Testing (Tutorial With Integration Testing Example). [Online] [Last accessed 21st May 2020, 14:32 o’clock]

• SQLite: SQLite Home. What is SQLite? [Online] [Last accessed 2nd June 2020, 12:07 o’clock]

• Square. Inc.: [Library] [Last used 2nd June, 17:30 o’clock]

• Swift (a): About Swift. [Online] [Last accessed 9th May 2020, 10:35 o’clock]

• Swift (b): Error Handling. [Online] [Last accessed 1st June 2020, 13:35 o’clock]

• Visual Paradigm: What is User Story? [Online] [Last accessed 1st June 2020, 16:00 o’clock] • W3schools (a): JavaScript Switch Statement. [Online] [Last located 1st June 2020, 17:08 o’clock]

43 Bjergø – 66818 S2026631-3 03-06-2020 Christensen – 66523 Roskilde University 4th semester Kirkegaard – 65451 Subject Module Project - CS Work – 66712

• W3schools (b): Java Enums. [Online] [Last accessed 1st june 2020, 16:32 o’clock]

• WhatWG: HTML Standard. [Online] [Last accessed 1st June, 18:34 o’clock]

44