Giter VIP home page Giter VIP logo

swot's Introduction

swot

Quiz maker written using the MEAN stack (MongoDB, Express, AngularJS, and Node.js). This is a learning project that is still in the early stages of development.

The primary goal of swot is to create an advanced quiz editor that is capable of more than just simple flashcard style questions, while keeping the UI simple and easy to use.

Current capabilities include:

  • Ability to create, save and take quizzes
  • Rich formatting in the questions (support for font styles, lists, images, etc. all courtesy of ckeditor)
  • Navigate and take quizzes with instant feedback and automatic score-keeping
  • Support for multiple question types, including fill-in and multiple choice

Support for a greater variety of question types including true/false, short answer, matching, check all that apply, and others - along with more grading options and the ability to show supplemental information - is all coming soon.

Launching

swot requires Node and npm (which should be installed as part of Node), and can be built and launched on UNIX platforms as well as Windows.

In addition, MongoDB should be installed and running. swot assumes that MongoDB is listening on the default port, 27017, but this may be changed by setting the MONGODB_URL environment variable before launching the app (if the environment variable is not specified, it defaults to localhost:27017/swot).

Finally, you must also have grunt installed globally:

npm install -g grunt-cli

Once these prerequisites are met, building and launching swot should be fairly simple. After cloning the repo, switch to the directory in the terminal or command line and run the following commands:

npm install
npm start

The app should now be running on port 3000. You should be able to connect to http://localhost:3000 using the browser and see a login screen (there isn't really an actual home page yet). Click register at the top right and create an account, after which you should be able to create and take quizzes.

Note: During development, you can instead run grunt nodemon to launch the app using nodemon. This will automatically restart the server whenever any files are changed.

Running Tests

swot uses the following testing frameworks:

  • mocha: Test runner.
  • chai: Assertion library. swot uses BDD style assertions using expect.
  • sinon: Mock/stub framework.
  • Protractor: Framework for writing end-to-end (e2e) tests.

To run the unit tests, you will need to have mocha installed globally: npm install -g mocha. Then the tests may be run using grunt test.

To run the end-to-end tests, you will need to have Protractor installed globally:

npm install -g protractor

Then you will need to install the selenium standalone server. Protractor comes with a script to help download and install it - run the following command to do so (use sudo on Linux):

webdriver-manager update

After completing the above setup, you should be able to run the end-to-end tests using grunt:

grunt test:e2e

The test:e2e task is a shortcut that essentially runs all of the following commands:

  • Launches the app with a testing configuration (make it run on port 3033 instead of the default 3000, and have it connect to a separate database called swot_test instead of swot):
    grunt env:test shell:app
  • Starts selenium server:
    webdriver-manager start
  • Runs protractor:
    protractor e2e.conf.js

While doing development, it is recommended to run each of the above commands in 3 separate terminals. This way, you're not repeatedly launching and bringing down the app, as well as selenium server, without need (rather, you can restart the app only if you've made any server-side changes, and you can probably just leave selenium running all the time). It also keeps the output from running the tests separate, instead of mixing it all in one place. However, if you just want to just run the tests once, quickly, then this can save a lot of time and remembering.

Note also that the end-to-end tests can take several minutes to run. If you're doing work on the quiz editor, it's unlikely that you broke anything related to the login/registration functionality, so you may want to save some time by skipping these tests. To do this, you can temporarily edit the file filter in e2e.conf.js by changing this line:

specs: ['test/e2e/**/*.spec.js'],

To this (for example):

specs: ['test/e2e/editQuiz/*.spec.js'],

This way, you will only be running the quiz editor specs when launching protractor.

Finally, note that there's another shortcut task in grunt that allows you to run both the unit tests as well as end-to-end tests using one command:

grunt test:all

This runs the unit tests, followed by the end-to-end tests.

swot's People

Contributors

mortonfox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

swot's Issues

Topics with long names cause some UI issues

If a topic's name is really long, it causes ugly wrapping in the sidebar:

swot - long topic name sidebar

It also causes the the Edit button to be displaced in the main content area:

swot - long topic name

Not sure yet what the best approach would be to deal with long topic names. Ideas:

  • Truncate long topic names with ellipses in the sidebar, and don't allow wrapping.
  • Make the sidebar resizable by dragging (would need to remember the user's preferred width)
  • In the main content area, topic names should probably wrap to the next line. The edit button should stay in place regardless of how long the topic name is.

Support for multiple sessions

It should be possible to have multiple users (or the same user logged into multiple machines) edit the same quiz and see each other's changes without anything getting overwritten. Ideally, changes made in one session should be visible as close to real time as feasible in all other simultaneously connected sessions. If one client temporarily disconnects then reconnects, all changes made in all other sessions should get pushed to them before they are allowed to save anything. If conflicting changes are made, the UI needs to provide a way to merge/resolve these conflicts.

Related: Something similar may need to be done for topics. Perhaps there should be a common scheme for broadcasting all changes (to quizzes, topics, and whatever else might be added in the future) to all connected clients.

The implementation of this will likely be dependent on #5.

Update and clean up dependencies

A lot of dependencies are out of date. Most notably, need to upgrade Express from 3 to 4.

You can show a list of outdated node packages by running npm outdated

For bower dependencies, you can just run bower list and it will show the latest version available for each dependency.

Bower dependencies should be cleaned up a bit - some of the packages are using specific builds that aren't tagged with version numbers (for example, angular animate is using version "1.2.10-build.2164+sha.8b395ff" right now). Such dependencies should be resolved to a specific released version.

End-to-end tests need to be brought up to date first before working on this issue to make sure nothing breaks as a result of the upgrades.

Implement better logging

Need to add error logging to the app. Errors (and possibly all requests) should be persisted to the database on the live site, whereas in dev, they should just be dumped to the console. Additional metadata such as current user and quiz/topic should get logged along with the error wherever possible.

As for choice of logging framework, it will probably either be winston.js or bunyan. here are some resources that may be useful in making the decision:

Support for uploading images in question editor

Currently, images within questions (or in the supplemental info field) have to be uploaded externally and linked using a URL. It would be more convenient to be able to upload an image directly by browsing, or by pasting from the clipboard. There are various plugins available to do this in CKEditor:

Ideally, in addition to basic support for image uploads, this should support pasting an image from the clipboard, or by dragging & dropping (like in GitHub's issue editor). It would also be really cool (though probably impossible due to security limitations) to have a button for inserting a screen clipping (like in Word); failing that, it should at least be possible to easily crop an image after inserting it.

As part of this, we would need to think about setting individual file size limitations, as well as total storage quotas per user (for all images, and other data).

Demo mode (Allow users to try out swot without having to register)

Currently, users are forced to register before they can see what the application is even capable of. (Also, currently there isn't much of a homepage that explains what swot even is, but that should be a separate issue.) This issue is a request for a "demo mode" of swot where users can try out editing, saving, and taking quizzes without having to register.

In demo mode, all quizzes that are "saved" will be stored in the browser's local storage instead of the database. Also, a site-wide banner will be present at the bottom of the page reminding users that their quizzes are only being stored in their browser and may be lost if they clear their cache, and also encouraging them to register.

Editor toolbar covers up question menu

The rich text editing toolbar covers up the question menu:

swot - toolbar

This makes it impossible to see the question number, switch question type, or access the question settings panel without clicking away first. It also requires hacks in the e2e test code (see /test/e2e/editQuiz/quizEditor.js, search for hideQuestionToolbar).

We need to make more room for the toolbar, though ideally without making the questions themselves take up more space. Ideas:

  • Expand the question editing area to make room for the toolbar when the user is editing that particular question, and then collapse it back when moving to a different question.
  • Don't pop up the full toolbar - just show a single row for the most common formatting options, but provide a way to see advanced formatting options.
  • Show the toolbar inside the question editing area at the bottom (like gmail's composer).

Allow quiz reordering, and moving quizzes between topics

It should be possible to change the order in which quizzes appear within a topic using drag and drop. It should also be possible to drag a quiz from one topic to another.

The backend implementation for this has been started in commit ce850e6, which contains the schema changes and a pre-save hook that would accomplish these via the Quiz.position and Quiz.topic "properties". The next step would be to add some routes to expose these properties via the API. However, rather than having separate routes for these properties, I'd like to use a single route for updating quizzes via a PATCH request, similar to how we update topic position (see commits a440989 and 9de6ccb).

However, if we go that route, then we should support PATCH for other quiz properties, including individual questions within the quiz. Thus, completion of this feature is dependent on fixing #5.

Question Type: Select all that apply

Create a new question type for "select all that apply" questions. For example:


Which of the following English monarchs were part of the House of Tudor? Select all that apply:

  • Charles II
  • Henry VI
  • Henry VIII
  • Edward VI
  • James I
  • Elizabeth I

To be decided:

  • Scoring: should this be all or nothing, or should partial credit be given if user identifies some but not all of the correct choices? What if they select all of the correct choices, but also include one extra (incorrect) choice?
  • Should this be its own question type, or just a variant of multiple choice? We could add a setting within the multiple choice question editor for "single select" vs "multiple select", where single select would be an ordinary multiple choice question (only one choice is correct), whereas multiple select would be the "select all that apply" type of question.
  • When displaying this type of question, should we always prepend the list of choices with a "Select all that apply" label, or make this optional? Maybe automatically include it in the question editor textbox when this question type is initially selected, but allow the user to edit/delete it?

Undo support for deleting topics

Deleting a topic deletes all quizzes associated with that topic; it also deletes all subtopics, and all quizzes associated with those topics. As such, it's kind of a dangerous operation, and the user should have the ability to undo it.

There are a couple related issues here:

  • The UI should be improved to make it clearer what exactly is going to be deleted when the user deletes a topic. For instance, when deleting a parent topic, the UI should make it clear that all subtopics and their quizzes will also be deleted by calling it out visually (perhaps shade all topics marked for deletion in red and/or animate them in the sidebar; or also list out all the topics and quizzes that will be deleted).
  • Perhaps we should not delete subtopics when deleting a parent topic, and instead only delete the parent topic, and move all the subtopics one level up the hierarchy.

TBD:

  • Should the ability to undo topic deletion be permanent, or will it only be available immediately after deleting? If it's permanent, then how will that look like - should we have a special section in the sidebar for deleted topics?

Support for multi-part quizzes

For long quizzes than span multiple related concepts, it may be helpful to be able to split up the quiz into multiple "parts". This would provide a logical grouping for the questions that would help orient the quiz taker. It should also hopefully provide for a better UI experience when taking or editing a long quiz (instead of scrolling through a hundred questions, each individual part could be on its own separate page/panel).

When taking a quiz that has multiple parts, the sidebar should display a hierarchical view of the questions within each part (instead of just a flat list). As the user is advancing through the quiz, the "part" should have its own separate page to make it obvious that they have just advanced to a different part.

When editing a multipart quiz, It should be possible to specify a name for each part, as well as any additional info that should appear on the part's intro page (e.g., an explanation of what this part is about, or any special instructions). This should support rich formatting with images.

This is an "advanced" feature - it's important not to sacrifice the usability/ease of use of simple quizzes that don't have multiple parts. As such, the current notion of "flat" quizzes should remain the default.

(TBD: Whether we should allow nesting parts within parts.)

Self-graded short response questions

Need to add a new question type for short response. These will not be automatically graded - the quiz taker will be shown the correct answer after submission, and given the option to mark their submission as correct or incorrect.

Deleting a quiz sometimes does not delete it from the parent topic's "quizzes" array

Not sure yet under what circumstances this occurs, but after deleting a quiz, the quiz pre-remove hook (/lib/quiz.js:135) sometimes fails to remove the quiz from its parent topic's "quizzes" array. This results in an error whenever you try to load the quiz hierarchy:

  TypeError: Cannot call method 'toObject' of null
    at /app/lib/quiz/quizService.js:200:29
    at Array.map (native)
    at Promise.promise.promiseDispatch (/app/node_modules/q/q.js:759:13)
    at Function._.map._.collect (/app/node_modules/underscore/underscore.js:97:56)
    at _fulfilled (/app/node_modules/q/q.js:797:54)
    at /app/lib/quiz/quizService.js:199:32
    at /app/node_modules/q/q.js:1184:26
    at self.promiseDispatch.done (/app/node_modules/q/q.js:826:30)
    at /app/node_modules/q/q.js:525:49
    at flush (/app/node_modules/q/q.js:108:17)

This essentially makes the site unusable from that point onward, since the quiz hierarchy gets loaded every time you visit the "My Quizzes" page.

The approximate sequence of events leading to the error was:

  1. In the "General" topic, I clicked "Create Quiz".
  2. I realized I was in the wrong topic; however, I didn't delete the quiz right away. Instead, I went back to "My Quizzes". (I didn't add any questions or specify a name.)
  3. I opened the quiz for editing again (the name got defaulted to "New Quiz", as expected).
  4. I deleted the quiz using the gear dropdown at the top right.
  5. It said the quiz got deleted successfully, but the "My Quizzes" page failed to load.

Need to figure out why the pre-remove hook didn't fire - or maybe it did fire, but in that case I would need to figure out why it didn't do what it was supposed to do. In the meantime, as a temporary safeguard, it may be a good idea to filter out any null quizzes inside quizService.getQuizzesAndSubtopics() instead of blindly calling quiz.toObject.

Use Angular for navigation, and don't mix server-side and client-side templating

This project currently uses both client-side (angular) and server-side (Jade) templating, which results in messy code and inconsistency. I'd like to move away from server-side templating and rely more on Angular for navigation and data retrieval. Server-side templating should be limited to the main layout ("shell") page, which should just include all common scripts and stylesheets. I'm not sure whether the layout page should include the header, as that is something that might need to change down the line depending on which page you're on.

TBD: Whether to use Angular's built in angular-route, or ui-router.

To make things more consistent, I would also like to move away from using Jade as the templating engine for Express, and instead move to EJS whose syntax is more similar to HTML. While I like Jade's syntax and conciseness, I don't like the constant context-switching when working with Jade views vs HTML partials.

Improve quiz editing API to allow more granular saving

Currently, editing quiz questions results in re-saving the entire quiz from scratch (including all questions) any time a change is made. This is not very efficient, especially with auto-save. The backend should be rewritten to add support for more granular saving (probably using PATCH requests, like with topics). If only one question got changed, then ideally the request body should only include that question, and only that one question should be rewritten when saving to the database. While we're at it, might as well make the API for editing quizzes/questions adhere to REST principles.

Occasional "VersionError: No matching document found" when trying to delete topics containing subtopics

Received this in the live app when trying to delete a topic containing 4 subtopics:

2014-08-31T19:39:54.874460+00:00 heroku[router]: at=info method=DELETE path="/topics/5403752f5870060200c1afa7" host=*** request_id=b343df90-4fe3-410a-9b44-482850f31fad fwd="***" dyno=web.1 connect=0ms service=31ms status=500 bytes=752
2014-08-31T19:39:54.875594+00:00 app[web.1]: VersionError: No matching document found.
2014-08-31T19:39:54.875605+00:00 app[web.1]:     at Server.Base._callHandler (/app/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/base.js:442:41)
2014-08-31T19:39:54.875614+00:00 app[web.1]:     at emit (events.js:98:17)
2014-08-31T19:39:54.875607+00:00 app[web.1]:     at /app/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:485:18
2014-08-31T19:39:54.875613+00:00 app[web.1]:     at null.<anonymous> (/app/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:191:13)
2014-08-31T19:39:54.875611+00:00 app[web.1]:     at emit (events.js:95:17)
2014-08-31T19:39:54.875601+00:00 app[web.1]:     at handleSave (/app/node_modules/mongoose/lib/model.js:126:23)
2014-08-31T19:39:54.875608+00:00 app[web.1]:     at MongoReply.parseBody (/app/node_modules/mongoose/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js:68:5)
2014-08-31T19:39:54.875610+00:00 app[web.1]:     at null.<anonymous> (/app/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:443:20)
2014-08-31T19:39:54.875602+00:00 app[web.1]:     at /app/node_modules/mongoose/lib/utils.js:408:16
2014-08-31T19:39:54.878511+00:00 app[web.1]: DELETE /topics/5403752f5870060200c1afa7 500 31ms - 21b
2014-08-31T19:39:54.875604+00:00 app[web.1]:     at /app/node_modules/mongoose/node_modules/mongodb/lib/mongodb/collection/core.js:637:9

I suspect the fact that all of the topics and subtopics were created in rapid succession may have something to do with this error - maybe one save call did not finish before another one was issued.

Multiple choice: setting to randomize choice order

There should be an option to allow randomizing the order in which choices appear whenever the question is displayed in the context of taking the quiz. The setting should be off by default, and should only be visible when the settings pane for the question is opened.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.