CaptchaView.test.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /**
  2. * Copyright (C) 2024-present Puter Technologies Inc.
  3. *
  4. * This file is part of Puter.
  5. *
  6. * Puter is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License as published
  8. * by the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Affero General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Affero General Public License
  17. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. import { describe, it, beforeEach, afterEach } from 'mocha';
  20. import { expect } from 'chai';
  21. import sinon from 'sinon';
  22. import jsdom from 'jsdom';
  23. const { JSDOM } = jsdom;
  24. // Mock the DOM environment
  25. const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>');
  26. global.window = dom.window;
  27. global.document = dom.window.document;
  28. global.HTMLElement = dom.window.HTMLElement;
  29. global.customElements = dom.window.customElements;
  30. // Mock the captchaHelper
  31. const captchaHelper = {
  32. isCaptchaRequired: sinon.stub()
  33. };
  34. // Mock the grecaptcha object
  35. global.grecaptcha = {
  36. ready: sinon.stub().callsFake(cb => cb()),
  37. execute: sinon.stub().resolves('mock-token'),
  38. render: sinon.stub().returns('captcha-widget-id')
  39. };
  40. // Import the module under test (mock import)
  41. const CaptchaView = {
  42. prototype: {
  43. connectedCallback: sinon.stub(),
  44. disconnectedCallback: sinon.stub(),
  45. setRequired: sinon.stub(),
  46. isRequired: sinon.stub(),
  47. getValue: sinon.stub(),
  48. reset: sinon.stub()
  49. }
  50. };
  51. describe('CaptchaView', () => {
  52. let captchaElement;
  53. beforeEach(() => {
  54. // Create a mock CaptchaView element
  55. captchaElement = {
  56. ...CaptchaView.prototype,
  57. getAttribute: sinon.stub(),
  58. setAttribute: sinon.stub(),
  59. removeAttribute: sinon.stub(),
  60. appendChild: sinon.stub(),
  61. querySelector: sinon.stub(),
  62. style: {},
  63. dataset: {},
  64. captchaWidgetId: null,
  65. captchaContainer: document.createElement('div')
  66. };
  67. // Reset stubs
  68. Object.values(CaptchaView.prototype).forEach(stub => {
  69. if (typeof stub.reset === 'function') stub.reset();
  70. });
  71. captchaHelper.isCaptchaRequired.reset();
  72. grecaptcha.ready.reset();
  73. grecaptcha.execute.reset();
  74. grecaptcha.render.reset();
  75. });
  76. describe('setRequired', () => {
  77. it('should show captcha when required is true', () => {
  78. // Setup
  79. captchaElement.setRequired.callsFake(function(required) {
  80. this.required = required;
  81. if (required) {
  82. this.style.display = 'block';
  83. } else {
  84. this.style.display = 'none';
  85. }
  86. });
  87. // Test
  88. captchaElement.setRequired(true);
  89. // Assert
  90. expect(captchaElement.required).to.be.true;
  91. expect(captchaElement.style.display).to.equal('block');
  92. });
  93. it('should hide captcha when required is false', () => {
  94. // Setup
  95. captchaElement.setRequired.callsFake(function(required) {
  96. this.required = required;
  97. if (required) {
  98. this.style.display = 'block';
  99. } else {
  100. this.style.display = 'none';
  101. }
  102. });
  103. // Test
  104. captchaElement.setRequired(false);
  105. // Assert
  106. expect(captchaElement.required).to.be.false;
  107. expect(captchaElement.style.display).to.equal('none');
  108. });
  109. });
  110. describe('isRequired', () => {
  111. it('should return the current required state', () => {
  112. // Setup
  113. captchaElement.required = true;
  114. captchaElement.isRequired.callsFake(function() {
  115. return this.required;
  116. });
  117. // Test & Assert
  118. expect(captchaElement.isRequired()).to.be.true;
  119. // Change state
  120. captchaElement.required = false;
  121. // Test & Assert again
  122. expect(captchaElement.isRequired()).to.be.false;
  123. });
  124. });
  125. describe('getValue', () => {
  126. it('should return null when captcha is not required', () => {
  127. // Setup
  128. captchaElement.required = false;
  129. captchaElement.getValue.callsFake(function() {
  130. return this.required ? 'mock-token' : null;
  131. });
  132. // Test & Assert
  133. expect(captchaElement.getValue()).to.be.null;
  134. });
  135. it('should return token when captcha is required', () => {
  136. // Setup
  137. captchaElement.required = true;
  138. captchaElement.getValue.callsFake(function() {
  139. return this.required ? 'mock-token' : null;
  140. });
  141. // Test & Assert
  142. expect(captchaElement.getValue()).to.equal('mock-token');
  143. });
  144. });
  145. describe('reset', () => {
  146. it('should reset the captcha widget when it exists', () => {
  147. // Setup
  148. captchaElement.captchaWidgetId = 'captcha-widget-id';
  149. global.grecaptcha.reset = sinon.stub();
  150. captchaElement.reset.callsFake(function() {
  151. if (this.captchaWidgetId) {
  152. grecaptcha.reset(this.captchaWidgetId);
  153. }
  154. });
  155. // Test
  156. captchaElement.reset();
  157. // Assert
  158. expect(grecaptcha.reset.calledWith('captcha-widget-id')).to.be.true;
  159. });
  160. });
  161. });